39

I've found an article claiming that $_SERVER['PHP_SELF'] is vulnerable to XSS.

I'm not sure if I have understood it correctly, but I'm almost sure that it's wrong.

How can this be vulnerable to XSS attacks!?

<form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>">
  <!-- form contents -->
</form>
Danny Beckett
  • 20,529
  • 24
  • 107
  • 134
McRonald
  • 995
  • 4
  • 10
  • 13
  • 2
    See also: http://seancoates.com/blogs/xss-woes – giraff Jul 28 '11 at 19:30
  • 4
    It does not answer the question, but has been overlooked in all the answers so far: As the action attribute can take a relative URI, keep it empty to link to the same page: `action = ""` - this is what `$_SERVER['PHP_SELF']` expresses as well but without the data. And when you then look into the HTML reference of your choice, you can see that this is also it's default value, so you can leave it out. How easy was that? – hakre Dec 26 '14 at 16:09
  • Providing an empty action attribute is not valid in HTML 5, and leaving out the attribute altogether makes your page Susceptible to iframe attacks. – Duncan Apr 11 '16 at 06:26

6 Answers6

40

To make it safe to use you need to use htmlspecialchars().

<?php echo htmlspecialchars($_SERVER["PHP_SELF"], ENT_QUOTES, "utf-8"); ?>

See A XSS Vulnerability in Almost Every PHP Form I’ve Ever Written for how $_SERVER["PHP_SELF"] can be attacked.

John Conde
  • 217,595
  • 99
  • 455
  • 496
  • 23
    some explanation (why it's unsafe without performing this operation?) would be highly appreciated – McRonald May 21 '11 at 10:09
  • 1
    First off - I've tested multiple versions of this in modern browsers - none seem to execute the script I attach to the content. Second, why is using `` any different from using regular links (manually typed?) - a user can manipulate those just as easily? So, is this no longer as big a threat? (Modern browsers)? And, why is using this global variable any different from using a full url manually? – junkfoodjunkie Apr 12 '17 at 18:26
  • Sorry, the link above error's : **Error establishing a database connection** – user10089632 Aug 11 '17 at 05:32
  • and can you please say if all the superglobals arrays and constants are vulnerable to this attack? – user10089632 Aug 11 '17 at 05:35
30

It is indeed a XSS vulnerability. I do understand that you believe it may not harm your website, but this doesn't mean it is not real.

If you do not believe it, try the following:

We assume you have a page such as "registration.php". We assume you have a form where action is:

<?php echo $_SERVER['PHP_SELF']; ?>

as you put it down indeed:

<form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>">
  <!-- form contents -->
</form>

Now simply append the string below

%27%22/%3E%3Cscript%3Ealert(1)%3C/script%3E

It is not actually hard to understand, because PHP_SELF is a reflection of the URL, your application will read whatever you put in the URL and echo it. It is simple as that.

htmlspecialchars should take care of the matter, no reason to dispute the evidence.

<form method="post" action="<?php echo htmlspecialchars($_SERVER['PHP_SELF']); ?>">
   <!-- form contents -->
</form>

However, even this is a first step in stealing a cookie, it's not that it take place automatically. Even if it's quite easy to craft the attack (as the attacker will register on your site and will see how the cookie looks...etc.), a series of other factors must be true to get to the point of having a cookie stealing situation. For instance, the cookie must not be expired. Than it depends of how complex the cookie is. Than maybe you have other precautions in placed on server, it doesn't have to be all authentication based on the presence of cookie!

While I do believe it is rather difficult and really bad programming for all conditions to met (even if yahoo.mail for example had such a vulnerability and if you look on internet you will find even the exploit and the cookie decoder), the XSS is real and who knows what a crafty attacker may do if your site suffer of it. The cure is simple...

Community
  • 1
  • 1
Florin Sima
  • 1,495
  • 17
  • 13
20

The very article you linked gives you:

http://www.example.com/form.php/%22%3E%3Cscript%3Ealert(‘xss attack’)%3C/script%3E%3Cbr%20class=%22irrelevant

what's not clear?

Edit: this is an XSS attack because I can hide a link from my site to yours with some JS added to the URL which sends me your cookies so the moment you click that link, you are pwnd.

chx
  • 11,270
  • 7
  • 55
  • 129
5

You should be using filter_input() to access superglobals in PHP. If you set the filter to FILTER_SANITIZE_FULL_SPECIAL_CHARS it will strip the unsafe characters typically used in XSS. Given your example:

<form method="post" 
    action="<?php filter_input(INPUT_SERVER, 'PHP_SELF', FILTER_SANITIZE_FULL_SPECIAL_CHARS); ?>">
<!-- form contents -->
</form>
Adam Bowen
  • 346
  • 3
  • 9
0

The vulnerability is that a user can enter malicious JavaScript codes in the form. To prevent this, htmlspecialchars function is used.

Predefined characters (like >, <, ", ') are converted into entities(> < etc)

htmlspecialchars($_SERVER["PHP_SELF"]) ensures that all submitted form variables are converted into entities.

To read more about this vulnerability, visit: https://www.w3schools.com/php/php_form_validation.asp

Another link that can help you: https://www.google.com/amp/s/www.bitdegree.org/learn/php-form-validation/amp

Digi Coder
  • 76
  • 1
  • 6
0

I am studying this issue about the PHP_SELF variable and the XSS attack. There is something that I still can't understand: PHP_SELF variable is suposed to reference the name of the script file (the script that is running). Then, why does it take its value from the URL? (allowing the XSS problem).