...

View Full Version : Secure $_SERVER superglobals?



alex375
09-03-2007, 01:23 PM
Hallo all!

I've read on the weekend, that $_SERVER superglobals are not safe.
PHP Arcitect's Guide to PHP Security states:


// Given URL of: php.php/%22%3E%3Cscript%3Ealert(‘xss’)%3C/script%3E%3Cfoo
// Server Environment Variables will be as follows:
$_SERVER[“PATH_INFO”] = /”><script>alert(‘xss’)</script><foo
$_SERVER[“PATH_TRANSLATED”] =/home/forum/F/”><script>alert(‘xss’)</script><foo
$_SERVER[“PHP_SELF”] = /php.php/”><script>alert(‘xss’)</script><foo


But the book not clearly describes how this variables can be exploited.

Should I realy test all $_SERVER superglobals or only those I am using somewhere in the program, eg $_SERVER[“PHP_SELF”]?

would I not spoil their content if I do following:
$_SERVER[“PHP_SELF”]=htmlspecialchars($_SERVER[“PHP_SELF”])?

Are there any standard methods to make superglobals safe?

thx in advance

rafiki
09-03-2007, 01:30 PM
i dont think that PHP will allow you to set $_SERVER['PHP_SELF'] because its name would be reserved, however you can


$var = htmlspecialchars($_SERVER['PHP_SELF']);
//then use $var accordingly

not sure if thats the best/safest way to clean super globals

alex375
09-03-2007, 01:54 PM
rafiki, thank you for your quick answer, but the main question still is:
should i secury them?

If i have in form eg

action="$_SERVER[“PHP_SELF”]" (this is only a general example)

But teoretically if some javasctipt code is ebedded in it, it could be quite dangerous..

kbluhm
09-03-2007, 01:57 PM
You can Indeed change superglobal values:

<?php

echo $_SERVER['PHP_SELF'];

$_SERVER['PHP_SELF'] = 'Hello.';

echo "\n", $_SERVER['PHP_SELF'];

?>
Outputs:

/folder/file.php
Hello.

rafiki
09-03-2007, 02:00 PM
if your paranoid why dont you just set the form action to pagename.php

alex375
09-03-2007, 02:03 PM
I am not paranoid:) and I don't use PHP_SELF in the forms, as I said that was a general example, not my special case. I just want to make it realy hard to hack my site ;)

so it is possible, but how than I can strip the content of PHP_SELF or other server superglobals in the way to make them completely safe?
I assume I should expect no danger from the superglobals i don't even use, am I right?

rafiki
09-03-2007, 02:09 PM
you could use functions to check and see if the super globals contain anything like <script> etc..

alex375
09-03-2007, 02:16 PM
would it not be a little too hard if I use something like:


$_SERVER= array_map('htmlspecialchars', $_SERVER);

I could slow down the server...

any other ideas?

Mwnciau
09-03-2007, 02:35 PM
'HTTP_ACCEPT'
Contents of the Accept: header from the current request, if there is one.
'HTTP_ACCEPT_CHARSET'
Contents of the Accept-Charset: header from the current request, if there is one. Example: 'iso-8859-1,*,utf-8'.
'HTTP_ACCEPT_ENCODING'
Contents of the Accept-Encoding: header from the current request, if there is one. Example: 'gzip'.
'HTTP_ACCEPT_LANGUAGE'
Contents of the Accept-Language: header from the current request, if there is one. Example: 'en'.
'HTTP_CONNECTION'
Contents of the Connection: header from the current request, if there is one. Example: 'Keep-Alive'.
'HTTP_HOST'
Contents of the Host: header from the current request, if there is one.
'HTTP_REFERER'
The address of the page (if any) which referred the user agent to the current page. This is set by the user agent. Not all user agents will set this, and some provide the ability to modify HTTP_REFERER as a feature. In short, it cannot really be trusted.
'HTTP_USER_AGENT'
Contents of the User-Agent: header from the current request, if there is one. This is a string denoting the user agent being which is accessing the page. A typical example is: Mozilla/4.5 [en] (X11; U; Linux 2.2.9 i586). Among other things, you can use this value with get_browser() to tailor your page's output to the capabilities of the user agent.

Those are the only ones that are set by the headers when I looked at the predefined variables (http://uk2.php.net/reserved.variables) list that I could find

rafiki
09-03-2007, 02:39 PM
if you want to run checks only on certain super globals use


//if PHP_SELF contains <script> die()
if (ereg("<script>", {$_SERVER['PHP_SELF']})){
$error = 'No way Hosay... no attacks on my site.';
die($error);
}else{
print $_SERVER['PHP_SELF'];
}

Mwnciau
09-03-2007, 02:47 PM
Surely javascript on your site would only break it for the person with the headers? Javascript is run client side so it can only affect them...

rafiki
09-03-2007, 03:07 PM
you could have something like
; echo $mysql_conn; or something similar to echo out sensitive information..

Mwnciau
09-03-2007, 03:17 PM
you could have something like
; echo $mysql_conn; or something similar to echo out sensitive information..

Yes, but javascript can't access that data.

NancyJ
09-03-2007, 03:30 PM
Yes, but javascript can't access that data.

It doesnt need to. If the information is echoed out then it would be on the screen and the person could just write it down or copy it.

I have actually done some xss - just to prove a point. I modified a forum sig to have some malicious code in it that executed the PM script on their server. the javascript read their site cookies and PMed them to my account. Ofcourse, being the nice person I am I put an alert in the script to tell them it was being done.

The basic point is never echo out, execute or put in an sql query user input without sanitizing it first. That includes headers sent by the browser, which can be manipulated.

NancyJ
09-03-2007, 03:31 PM
you could have something like
; echo $mysql_conn; or something similar to echo out sensitive information..

You would have to exec() that for it to actually echo anything out.

rafiki
09-03-2007, 03:48 PM
You would have to exec() that for it to actually echo anything out.

im not sure how to do any XSS/hacking but i was trying to get to the point that sensitive information could be exposed to people it shouldnt.

alex375
09-03-2007, 03:53 PM
You would have to exec() that for it to actually echo anything out.
I don't quite get what do you mean by this.
I thought if I do:

echo $_SERVER['PHP_SELF']
which contains malicious JS it would be executed and thus you can succeed in your XSS attack.

NancyJ
09-03-2007, 04:30 PM
I don't quite get what do you mean by this.
I thought if I do:

echo $_SERVER['PHP_SELF']
which contains malicious JS it would be executed and thus you can succeed in your XSS attack.
Yes it can but if it contained PHP code (as in raf's example) you would need to exec() the variable for the code to be run.

CFMaBiSmAd
09-03-2007, 04:32 PM
Edit: Bascially says the same as above ^^

The posts mentioning exec() (probably should have been - eval()) pertain to a specific line of code that rafiki posted - ; echo $mysql_conn;

Those posts do not apply to the main topic of this thread.

rafki was theorizing that you could inject PHP code and that the PHP code would get executed. However, because the "php code" is contained in a string in a variable, the only ways to cause it to be executed would be if you used and eval() function, or you wrote that string to a php code file and that file was then executed (browsed to, included...)

NancyJ
09-03-2007, 04:33 PM
doh yes, I did mean eval - 4 letters, begins with e ;) at least someone knew what I meant.

alex375
09-04-2007, 12:10 AM
i've written the following function, which should make safe certain server superglobals, which are used on my site:

function protect_superglobals() {
$to_protect = array (
'HTTP_ACCEPT','HTTP_ACCEPT_CHARSET','HTTP_ACCEPT_ENCODING','HTTP_ACCEPT_LANGUAGE',
'HTTP_CONNECTION','HTTP_HOST','HTTP_REFERER','HTTP_USER_AGENT','SCRIPT_NAME'
);

foreach ($to_protect as $element) {
if (isset($_SERVER[$element])) {
$_SERVER[$element]=preg_replace ('/<.+>/i','',$_SERVER[$element]);
}
}
}



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum