7

I had someone run a pentest against an application recently and one of the critical problems it found was when some garbage was passed in a URL like this:

http://example.com/index.php/
%27%3e%3c%69%4d%67%20%53%72%43%3d%78%20%4f%6e%45%72%52%6f%52%3d%61%6c%65%
72%74%28%34%37%34%31%32%29%3e

The problem is that the attacker simply adds a slash then some encoded javascript (an image tag with alert box), which kills the page. Simple and effective attack.

How do I code against it? I am already cleaning all expected user inputs (such as when a user passes index.php?id=<script>alert(1)</script>). That part works fine.

How do I protect against unexpected data quoted below the first paragraph above? (Also, is there a specific name for this type of XSS attack?)

a coder
  • 7,530
  • 20
  • 84
  • 131
  • 1
    Are you accepting it and then serving it back as is to other users? The user is only affected if they click on the link correct? Or is it being parsed on your page and executing? – Matt Feb 19 '15 at 15:55
  • I'm curious where this URL is being displayed, or how the index.php page is processing `$_GET` (if at all?). – Jake Bathman Feb 19 '15 at 15:57
  • The app looks for two variables passed through URL: `id` and `sort`. Both of these are cleaned properly - no vulnerability was found that way. No other user-passed data should be displayed. – a coder Feb 19 '15 at 15:59
  • 2
    @acoder That JS in the URL shouldn't run by itself. Are you sure you don't echo it in the page or something? – Oriol Feb 19 '15 at 16:00
  • That this data is urlencoded should not make a difference - if you read it correctly by urldecoding then protection via `htmlentities()` will still be fine. – halfer Feb 19 '15 at 16:00
  • I am using $_SERVER['PHP_SELF'] in a URL, so that's the vulnerability. Need to clean that server var. – a coder Feb 19 '15 at 16:10
  • Cleaning `$_SERVER['PHP_SELF']` fixed it. Thanks for the replies. – a coder Feb 19 '15 at 16:11

5 Answers5

9

Be carefull with the use of $_SERVER['PHP_SELF]

You should do htmlspecialchars($_SERVER["PHP_SELF"]); or htmlentities($_SERVER["PHP_SELF"]);

And that's a normal XSS attack.

More info: Info

lmarcelocc
  • 1,301
  • 11
  • 21
5

I was using $_SERVER['PHP_SELF'] in an href tag, so that's where the JavaScript was triggered.

The solution is simple. I run PHP_SELF through a filter before using, and any passed garbage is cleaned and safe to use on the page.

a coder
  • 7,530
  • 20
  • 84
  • 131
  • 1
    What functions did you used to clean garbage? – Airy Mar 08 '20 at 13:59
  • This was a few years ago and don't have easy access to what I was doing in 2015, but am now using SCRIPT_NAME instead of PHP_SELF. I separately clean user posted (and retrieved from database) content through htmlpurifier. – a coder Mar 13 '20 at 22:18
  • @AbdulJabbarDumrai there is no one-size-fits-all answer for this. You need to generally consider `$_SERVER['PHP_SELF']` to be uncontrolled user input and treat it as such, much the same as accepting form data. Strictly validate the input against what is expected, and/or properly encode it according to your output format so that it is not evaluated. – Sammitch Mar 14 '20 at 00:10
1

The previous answers is already ok but for some reason htmlspecialchars() do not filter single quote. If you need to filter single quotes you will need to add a parameter in htmlspecialchars($_SERVER["PHP_SELF"], ENT_QUOTES)

1

How do I protect against unexpected data quoted below the first paragraph above?

filter_input( INPUT_SERVER, 'PHP_SELF', FILTER_SANITIZE_FULL_SPECIAL_CHARS );

Thanks, for @Sverri M. Olsen for expaining why to use filter_input instead of superglobals

https://stackoverflow.com/a/15103555/11173494

Also, is there a specific name for this type of XSS attack?

This is Stored XSS. The hacker could construct custom query to attack user by store malicious code.

@Sandeep Nair expained the difference between Stored XSS and Reflected XSS

https://stackoverflow.com/a/48893119/11173494

123
  • 2,169
  • 3
  • 11
  • 35
0

strip_tags() function may help. For example:

$str = 'index.php?id=<script>alert(1)</script>';    
echo "<pre>";
echo strip_tags($str), "\n";

The above will output:

index.php?id=alert(1)
  • Once the script tags are removed using strip_tags, the injected script cannot do any harm. Apart from that, validation of input for the 'id' field should provide better security. – Shahstewart Mar 14 '20 at 02:22