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('hacked')%3C/script%3E
$_SERVER['PHP_SELF']:
/form.php/"><script>alert('hacked')</script>
htmlspecialchars($_SERVER['REQUEST_URI']):
/form.php/"><script>alert('hacked')</script>
I think, the second should also be as the last...?
It sounds like you're confusing htmlspecialchars
with urlencode
.
htmlspecialchars
replaces characters with special meaning in HTML with &
-escaped entities. So, for example, '
becomes '
. It doesn't turn %22
into "
, 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=""
.