I have been doing some research on PHP Security Best Practices and came across a W3 page discussing the security risk of using $_SERVER["PHP_SELF"] in the form tag.

http://www.w3schools.com/php/php_form_validation.asp

I have tried to simulate the following code using IE and Chrome and neither produced the alert box as indicated in the article.

<form method=post action=$_SERVER['PHP_SELF']>
http://www.example.com/test_form.php/%22%3E%3Cscript%3Ealert('hacked')%3C/script%3E  

Can someone shed some light on this issue?

    It depends on how your webserver is configured to handle URLs. For example, if you had a rule like the following in a .htaccess file:

    RewriteEngine On
    RewriteRule ^test.php/(.*)$ test.php?$1

    then the URL form used above would indeed result in $SERVER['PHP_SELF'] containing undesirable data. Here's a print_r() of $SERVER on my test server:

    Array
    (
        [HTTP_HOST] => localhost
        [HTTP_CONNECTION] => keep-alive
        [HTTP_ACCEPT] => text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
        [HTTP_USER_AGENT] => Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.57 Safari/537.36
        [HTTP_ACCEPT_ENCODING] => gzip,deflate,sdch
        [HTTP_ACCEPT_LANGUAGE] => en-US,en;q=0.8
        [PATH] => *removed*
        [SystemRoot] => C:\Windows
        [COMSPEC] => C:\Windows\system32\cmd.exe
        [PATHEXT] => .COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC;.PY;.PL
        [WINDIR] => C:\Windows
        [SERVER_SIGNATURE] => 
        [SERVER_SOFTWARE] => Apache/2.4.3 (Win32) mod_authnz_sspi/0.1.0 PHP/5.4.6
        [SERVER_NAME] => localhost
        [SERVER_ADDR] => ::1
        [SERVER_PORT] => 80
        [REMOTE_HOST] => *removed*
        [REMOTE_ADDR] => ::1
        [DOCUMENT_ROOT] => C:/Apache24/htdocs
        [REQUEST_SCHEME] => http
        [CONTEXT_PREFIX] => 
        [CONTEXT_DOCUMENT_ROOT] => C:/Apache24/htdocs
        [SERVER_ADMIN] => root@localhost
        [SCRIPT_FILENAME] => C:/Apache24/htdocs/test.php
        [REMOTE_PORT] => 62764
        [GATEWAY_INTERFACE] => CGI/1.1
        [SERVER_PROTOCOL] => HTTP/1.1
        [REQUEST_METHOD] => GET
        [QUERY_STRING] => "><script>alert('hacked')</script>
        [REQUEST_URI] => /test.php/%22%3E%3Cscript%3Ealert('hacked')%3C/script%3E
        [SCRIPT_NAME] => /test.php
        [PATH_INFO] => /"><script>alert('hacked')</script>
        [PHP_SELF] => /test.php/"><script>alert('hacked')</script>
        [REQUEST_TIME_FLOAT] => 1386612112.075
        [REQUEST_TIME] => 1386612112
    )

      Do not link w3schools.com on this forum, please. Their information is often inaccurate and outdated. See here for more info.

      That said, you should be careful of how your site is set up in many, many ways. I believe the exploit you mention in your post can be understood as part of a broader family of exploits where you either a) fail to validate user input (namely, the query string) or b) your site is configured to report errors which end up just echoing user input.

      When you fail to validate data before working with it (e.g., making sure the user input in question contains an email address), then you are going to run into problems trying to use the user input in a particular way (e.g., sending an email to some user). [man]filter_var[/man] is a very useful function for validating user input.

      If your site is configured to just echo a user's input and show an error like this:

      echo "Your query string, " . $_GET["q"] . " doesn't make sense to me.";
      

      Then abusers can just formulate some kind of crazy query string that displays javascript on your site. You need to think more broadly about how user input can be abused to display information on your site that you do not want there. A good rule of thumb might be to never echo user input at all when displaying error messages.

        Write a Reply...