The code seems to be correct, but there are hidden dangers. Let's save it as foo.php and use it in a PHP environment
foo.php/%22%3E%3Cscript%3Ealert('xss')%3C/script%3E%3Cfoo
When you visit, you will find a Javascript alert popping up -- this is obviously another XSS injection vulnerability. The reason is found in
echo $_SERVER['PHP_SELF'];
The unfiltered value is output directly on this statement. To trace the source, let’s take a look at the description in the PHP manual
'PHP_SELF'<br><br>The filename of the currently executing script, relative to the document root. <br>For instance, $_SERVER['PHP_SELF'] in a script at the address <br>http://example.com/test.php/foo.bar would be /test.php/foo.bar. The __FILE__ <br>constant contains the full path and filename of the current (i.e. included) file.<br>If PHP is running as a command-line processor this variable contains the script <br>name since PHP 4.3.0. Previously it was not available.
The reason is very clear. It turns out that $_SERVER['PHP_SELF'] although "seems" to be an environment variable provided by the server, is indeed the same as $_POST and $_GET and can be changed by the user.
There are many other similar variables, such as $_COOKIE, etc. (If users want to "play with" their cookies, there is nothing we can do). The solution is simple, use functions such as strip_tags, htmlentities etc. to filter or escape.
echo htmlentities($_SERVER['PHP_SELF']);
-- Split --
The above examples make us need to maintain a cautious coding mentality at all times. Chris Shiflett summarized it quite straightforwardly in his blog . The two basic security ideas to prevent XSS are
Filter input<br>Escape output
I translated the above into "Filter input, escape output". For detailed information, please refer to this article on his blog , which is omitted here.