Is comparing a variable to $_SERVER['PHP_SELF'] safe usage?
I am a newbie to PHP still, so excuse this question if it seems silly, but I was wondering if this is safe usage of $_SERVER['PHP_SELF']
.
From my reading about what's wrong with it (prone to injection), I was wondering if it safe to compare it.
For example, 开发者_如何学编程I want the PHP/CSS stylesheet to change depending on the page the person is on, so in the PHP/CSS, it would have an if
statement checking $_SERVER['PHP_SELF']
to see if the page their visiting requires a different stylesheet.
Example:
if ($_SERVER['PHP_SELF'] === $thisPage) { }
Could malicious code affect me this way? Could I simply validate/cleanse it, then use it?
A better code example would be:
if ($_SERVER['SCRIPT_NAME'] === $thisPage) { }
Still, it depends on the contents of $thisPage. If $thisPage contains $_SERVER['PHP_SELF']
too, you should change that to $_SERVER['SCRIPT_NAME']
If you really can't use alternatives like __FILE__
and $_SERVER['SCRIPT_NAME']
, and make sure you understand the checks involved, yes.
For example, this URL: http://example.com/sick.php/mwuahahahaha
gives:
/sick.php/mwuahahahaha
Comparing is allowed, for non-critical things like CSS.
If there's no need to get the requested path (no URL rewrites), use $_SERVER['SCRIPT_NAME']
.
If you really need $_SERVER['PHP_SELF']
(rewrited URL), escape them when outputting (using htmlentities($_SERVER['PHP_SELF'])
.
Overview of variables:
__FILE__
: contains the full filesystem path from the active script. E.g.:
<?php /*test.php*/ include 'file.php';?>
<?php /*file.php*/ echo __FILE__;?>
Requesting test.php gives something like:/var/www/file.php
(and not/var/www/test.php
)$_SERVER['SCRIPT_FILENAME']
: contains the filesystem path of the requested script, e.g./var/www/test.php
$_SERVER['SCRIPT_NAME']
: contains the path of the requested script (like a filesystem one, but with the document root stripped), e.g./test.php
(even when using rewrited URL's)$_SERVER['PHP_SELF']
: contains a translated path (//
->/
,.
and..
resolved), but with additional path info.$_SERVER['REQUEST_URI']
: the worst of these, it contains the raw string in the request as in.GET [REQUEST_URI] HTTP/1.0
. (escaped) nullbytes are still visible in here. This is just the raw data betweenGET
(or whatever methode you use) andHTTP/1.0
(or whatever HTTP version you use)
A comparison of these variables:
I performed this test with nc
, but telnet
should suffice too. Server was from http://xampp.org/. The requested file is test.php
, which contains:
<?php
$properties = array('SCRIPT_FILENAME', 'SCRIPT_NAME', 'PHP_SELF', 'REQUEST_URI');
printf("% 15s: %s\n", '__FILE__', __FILE__);
foreach($properties as $property){
printf('% 15s: %s', $property, $_SERVER[$property]."\n");
}
?>
Test:
$ nc localhost 80
GET ///somedir/./../////test.php/somedata%20here?q%00=%25 HTTP/1.0
HTTP/1.1 200 OK
Server: Apache/2.2.14 (Unix)
[stripped]
__FILE__: /opt/lampp/htdocs/test.php
SCRIPT_FILENAME: /opt/lampp/htdocs/test.php
SCRIPT_NAME: /////test.php
PHP_SELF: /////test.php/somedata here
REQUEST_URI: ///somedir/./../////test.php/somedata%20here?q%00=%25
Using RewriteRule ^page/test test.php
:
$ nc localhost 80
GET ///somedir/./../page//.////test/somedata%20here?q%00=%25 HTTP/1.0
HTTP/1.1 200 OK
Server: Apache/2.2.14 (Unix)
[stripped]
__FILE__: /opt/lampp/htdocs/test.php
SCRIPT_FILENAME: /opt/lampp/htdocs/test.php
SCRIPT_NAME: /test.php
PHP_SELF: /test.php
REQUEST_URI: ///somedir/./../page//.////test/somedata%20here?q%00=%25
Conclusion: the safest variable to use in most cases is $_SERVER['SCRIPT_NAME']
.
Yes, the answer is simple and short:
if your files being called directly, like http://www.example.com/news.php
, your code is all right.
No malicious code can affect your site this way.
精彩评论