PHP_SELF and XSS
Asked Answered
A

7

40

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>
Audy answered 21/5, 2011 at 6:21 Comment(3)
See also: seancoates.com/blogs/xss-woesKrigsman
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?Sjoberg
Providing an empty action attribute is not valid in HTML 5, and leaving out the attribute altogether makes your page Susceptible to iframe attacks.Roney
S
42

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.

Selfinduction answered 21/5, 2011 at 6:44 Comment(5)
some explanation (why it's unsafe without performing this operation?) would be highly appreciatedAudy
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 <?php echo $_SERVER['PHP_SELF'];?> 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?Ocarina
Sorry, the link above error's : Error establishing a database connectionFloorman
and can you please say if all the superglobals arrays and constants are vulnerable to this attack?Floorman
tried it and at least for nginx I can say $_SERVER['PHP_SELF'] is safe. Found the javascript on $_SERVER['DOCUMENT_URI'] thoughBrianbriana
A
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...

Askew answered 22/1, 2013 at 13:55 Comment(3)
I can see how the attack may work. But I fail to see how using htmlspecialchars stops it.Lapsus
Great explanation. Thank you.Saipan
Excellent explanation. Yet another flaw of how interpreters can be manipulated if they do not understand the syntax of preceding or succeeding interpreters. Closing code early and injecting is fun :)Shahaptian
A
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.

Aron answered 21/5, 2011 at 6:35 Comment(3)
How this supposed to be an XSS attack?Audy
McRonald, Do you know what's XSS?Terminus
@McRonald: Read the first line here which describes exactly what is happening in this answer.Verleneverlie
C
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>
Calida answered 25/1, 2017 at 15:36 Comment(0)
C
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

Criticism answered 20/7, 2021 at 13:13 Comment(0)
C
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).

Capello answered 3/12, 2021 at 14:11 Comment(1)
It's not answer, much more of a questionLolly
H
0

I realized why something about the previous answers was unclear to me:
Basically, I thought example.php/some/extra/things would simply lead to "404 page not found". However, the server actually executes the /example.php anyway. (In contrast, it doesn’t work for /example.html/some/extra/things or /example.php"some/extra/things as both result in 404).

Since $_SERVER['PHP_SELF'] includes the part after .php/ (unlike $_SERVER['SCRIPT_NAME']), given a code like this:

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

If someone clicks on a link to /example.php/%22%3E%3Cscript%3Econsole.log('XSS')%3C/script%3E%3C!-- the browser sends a request to the server and receives:

<form method="post" action="/example.php/"><script>console.log('XSS')</script><!--">
    <!-- form contents -->
</form>

The result looks the same as /example.php/ in a browser but it runs the JS code.


A comment asked how htmlspecialchars can prevent it.
If one uses htmlspecialchars:

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

One gets:

<form method="post" action="/example.php/&quot;&gt;&lt;script&gt;console.log('XSS')&lt;/script&gt;&lt;!--">
    <!-- form contents -->
</form>

So it won't run the script.

Hinz answered 1/6 at 4:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.