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?
There are only values that the server controls and values that the user controls and you need to be aware of where a value comes from and hence whether it can be trusted for a certain purpose. $_SERVER['HTTP_FOOBAR'] for example is entirely safe to store in a database, but I most certainly wouldn't eval it.
The $_SERVER["PHP_SELF"] is a super global variable that returns the filename of the currently executing script. So, the $_SERVER["PHP_SELF"] sends the submitted form data to the page itself, instead of jumping to a different page. This way, the user will get error messages on the same page as the form.
$_SERVER is a superglobal variable in PHP. Superglobal variables are predefined variables in PHP that do not need to be declared by the user. $_SERVER contains data such as headers, paths, and script locations.
$_SERVER['REQUEST_URI'] contains the URI of the current page. So if the full path of a page is https://www.w3resource.com/html/html-tutorials.php, $_SERVER['REQUEST_URI'] would contain /html/html-tutorials. php.
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__;?>
/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 between GET
(or whatever methode you use) and HTTP/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']
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With