Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

any security concerns with $_SERVER['REQUEST_URI'] and header('location: ...');

Tags:

security

php

My website has a header, footer, and main content. If the user is not logged in, for the main content a login form may be displayed instead of the actual content.

On that login form I write the $_SERVER['REQUEST_URI'] in the session variable $_SESSION['redirect'].

My login form posthandler, which will log the user in, will send the user after successfully loggin in to this link via header('location: http://myserver.com'.$_SESSION['redirect']);

So if I go to myserver.com/somesite.php?somevar=10 it will show the proper site if you are logged in. Otherwise it will show the login form, however the URL in the address bar in the browser still says myserver.com/somesite.php?somevar=10 Then you enter your credentials and you are redirected to myserver.com/somesite.php?somevar=10, which will then - since you're now logged in - fully display.

I do not use the REQUEST_URI value for a form action or as a link href.

Also, any $_GET variables I use I first check if they match a regular expression (usually the variable will be a sha1 string or a otherwise randomly generated string of numbers and letters only, no special chars), and I always use prepared statements if the get variable is used in a db query.

My question is if there are any security concerns with that? Any ways to exploit this, enter something malicious into the url and then send it to another user for example...? Should I escape something somehow somewhere along the process?

like image 571
olli Avatar asked Mar 05 '13 02:03

olli


3 Answers

The key-rule is that you always check your input/outputs and see what you can and cannot control (and thus, what can be controlled by a user). On the basis of that, you apply security/sanitization measures.

If I understand your scenario correctly, you display the page, unless a user is not logged in. In that case you show a login box, and after succesful login you send the user back to the page he was trying to visit using the $_SERVER['request_uri'] (stored in a session).

So the user obviously can control this variable, he can browse to your page with some awkward characters. Thus you need to sanitize that. As @Wayne mentions in the comments, users can traverse your directory tree for instance.

Thus, like your $_GET variables, you will need to sanitize the $_SERVER['request_uri'] as well. There are many ways to do this. The most secure is arguably to check if the request_uri is an existing page, after sanitizing with html_entities() or something like that. Note that special directory traversal methods such as ../, // and ./ might slip through conventional sanization methods such as the aforementioned html_entities()

And to answer literally: Should I escape something somehow somewhere along the process? - Yes, everything, at the beginning of each process.

------ EDIT @ 12-12-2013 -----

(too long an answer for a comment, so I'll expain here how potentially a user can use directory traversal, incl. potential dangerous situations)

from the PHP manual:

$_SERVER['REQUEST_URI']: The URI which was given in order to access this page;
                         for instance, '/index.html'.

So, say I want to go to yourdomain.com/posts/post.php?../../../ssh your webapp will notice that i'm not logged in, store post.php?../../../ssh in a session and process logging in, after which it sends me back to the url. Because of the ../../../ssh part, I won't be send to post.php, but to a directory on your server named ssh which is below your webroot. For your convenience you've stored your SSH keys there. This seems safe, because it's out of the webroot no webuser should be able to access it. Yet, I can because of my ingenious addition to your url.

Although this is a little far-fetched, a properly configured http-server, chrooting environment etc. will prevent this, this example does show you that if you allow these characters to be added, they might make users access locations they are not supposed to.

Depending on your implementation, blindly adding $_SERVER['request_uri'] might also mean unwanted stuff gets added to a session, and if you store that session in a database, it will also get added to the database. I'm not really up-to-date how (in)secure PHP is, but I can imagine this allows for breaking out of session variables and potentially injecting stuff into your database.

Although not everything might be possible, and the example might not be really possible, it's better and not that hard to prevent this behaviour.

-- Small after thought: maybe the header('location'... stuff is insecure, but this: Is this PHP redirect insecure? shows its not really. Yet, like a commenter states over there: it's not that difficult to type urlencode()

like image 104
puredevotion Avatar answered Oct 09 '22 20:10

puredevotion


There are numerous security concerns with putting ANYTHING online. Having an identifiable pattern in post/get requests are a concern, but it depends on a lot of factors, mainly... what can a user get from messing with your site, and how liable are you for malicious intent of site users.

You should do some research in sanitizing your input, using session tokens would be the first thing you could do to ensure traffic to your login script is actually being generated by users on your site. These two common practices are the first steps in protecting agains sql injection, and cross-site scripting attacks. proper steps to ensure your data is protected, both through good database design, and good code design.

One of my favorite techniques is to configure my application to use custom http headers, and any script that receives data from a Super Global checks to ensure the custom header(s) are correctly supplied as on component of my security. These headers can be seen and sniffed easily by any hacker, but many attacks of a malicious nature are first performed by a script, and it's just one more step that's easy enough to deploy that makes you a harder target for these types of attacks.

A quick google search on fortifying a php based site turned up this article, which has some good tips: http://www.noupe.com/php/php-security-tips.html

like image 24
Brian Vanderbusch Avatar answered Oct 09 '22 18:10

Brian Vanderbusch


You'll never be 100% secure. You can have a look at OWASP Top Ten. These are the main security issues.

I think you should have a token (random number) associated to each user in $_SESSION, instead of $_SERVER['REQUEST_URI']. You could pass the REQUEST_URI by GET and token by POST (in a hidden input), and then validate it. If user login is needed to this URI, ensure that the received user token is equal to the session user token.

like image 1
Manolo Avatar answered Oct 09 '22 18:10

Manolo