Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is comparing a variable to $_SERVER['PHP_SELF'] safe usage?

Tags:

php

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?

like image 939
Tarik Avatar asked Aug 29 '10 19:08

Tarik


People also ask

Is $_ SERVER safe?

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.

What is the purpose $_ PHP_SELF variable?

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.

What is the $_ SERVER variable?

$_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.

What is $_ SERVER Request_uri?

$_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.


1 Answers

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 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'].

like image 196
Lekensteyn Avatar answered Oct 24 '22 20:10

Lekensteyn