Question

I write

http://www.mysite.com/form.php/%22%3E%3Cscript%3Ealert('hacked')%3C/script%3E

on URL. Now I press enter and the URL is:

http://www.mysite.com/form.php/"><script>alert('hacked')</script>

Now I post the form. When using $_SERVER['PHP_SELF'], htmlspecialchars works, with REQUEST_URI not. Why?

When and why should I use action="" or action=<?=$_SERVER['PHP_SELF']?> or action=<?=$_SERVER['REQUEST_URI']?>?

Here the result of the posts:

$_SERVER['REQUEST_URI']:
  /form.php/%22%3E%3Cscript%3Ealert('hacked')%3C/script%3E

htmlspecialchars($_SERVER['REQUEST_URI']):
  /form.php/%22%3E%3Cscript%3Ealert(&#039;hacked&#039;)%3C/script%3E

$_SERVER['PHP_SELF']:
  /form.php/"><script>alert('hacked')</script>

htmlspecialchars($_SERVER['REQUEST_URI']):
  /form.php/&quot;&gt;&lt;script&gt;alert('hacked')&lt;/script&gt;

I think, the second should also be as the last...?

Was it helpful?

Solution

It sounds like you're confusing htmlspecialchars with urlencode.

htmlspecialchars replaces characters with special meaning in HTML with &-escaped entities. So, for example, ' becomes &#039;. It doesn't turn %22 into &quot;, however, because %22 has no special meaning in HTML, so it's safe to display it without modification.

urlencode replaces characters with special meaning in URLs with hexadecimal character codes using %. So, for example, " becomes %22.

If you want a form to be handled by the same URL that is used to display it, always use action="" rather than action=<?=$_SERVER['PHP_SELF']?> or action=<?=$_SERVER['REQUEST_URI']?>. As you've already figured out, there are serious risks of cross-site scripting (XSS) if you use either of the $_SERVER variables, because they contain user input and therefore cannot be trusted. So, unless you have a good reason that you need to tweak the URL somehow, just use action="".

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top