4

I've heard it said over and over again that you should NEVER use $_SERVER['HTTP_REFERER']. Why?

I understand that this can easily be manipulated by a user, i.e., that the variable can be set to anything that the user wants. Thus, I completely understand why it shouldn't be trusted from a security standpoint. But if e.g. all pages that should be viewable only by authed users recheck that the user is authed, where's the danger in relying on this variable?

kittykittybangbang
  • 2,380
  • 4
  • 16
  • 27
  • One possible scenario is that authenticated user can manipulate this header and can get access to functions he/she is not entitled to. – Sameer Naik Aug 30 '15 at 01:21
  • @SameerNaik Why would you grant access to someone solely based on the HTTP referrer? – Mike Aug 30 '15 at 01:22
  • @SameerNaik Right, but again -- if each PHP file is written such that it checks user privileges each time it runs... problem solved? Right? – kittykittybangbang Aug 30 '15 at 01:24
  • @Mike I would not and trying to discourage its use – Sameer Naik Aug 30 '15 at 01:26
  • 1
    @kittykittybangbang If you are checking authz in every page (which is best practice) then what is the use case of using referrer header? – Sameer Naik Aug 30 '15 at 01:28
  • @SameerNaik most often I use it to send a user back to the page from whence he came after e.g. form submission, which triggers database insertion > variable updates > updates to original page content. – kittykittybangbang Aug 30 '15 at 01:30
  • 1
    @kittykittybangbang As a general rule of thumb, any time you get anything from the user, including GET, POST, HTTP referrer, user agent, etc., just ask yourself, "if the user were to change or omit this, would I be opening up a security vulnerability?" Redirecting the user based on their HTTP referrer could open up some sort of XSS type of vulnerability. If a malicious user were to modify the HTTP referrer they could get the user's browser to be forwarded wherever they want. Then again, if they are able to modify the HTTP referrer they likely can already do that anyway... food for thought. – Mike Aug 30 '15 at 01:33
  • mine is always blank, where do you send me after form submission then? –  Aug 30 '15 at 01:34
  • Then in that case, IMO, it would be better to redirect user to a known destination depending on the use case. In a multi-page, wizard like scenario you might end up sending them to step 2 of 3 instead of 1. – Sameer Naik Aug 30 '15 at 01:36
  • @Mike Thanks -- I like that rule of thumb. And I suppose it was in my use of this rule that I stumbled upon this question. What _could_ result from a malicious user's tampering with `$_SERVER['HTTP_REQUEST']`? – kittykittybangbang Aug 30 '15 at 01:36
  • @Dagon To a 'home' page, of sorts. * Shrug. * If you choose not to give me that information, that's certainly your prerogative. – kittykittybangbang Aug 30 '15 at 01:38
  • @kittykittybangbang It all depends on what you are doing with it. Treat it as "tainted", just like anything else the user supplies. Usually this means applying any corresponding escaping/filtering if you're going to echo it to the browser or save to a database. – Mike Aug 30 '15 at 01:39
  • seems like a poor approach when there are much better options –  Aug 30 '15 at 01:41
  • @Mike That was kind of my gut feeling on it, but was concerned about the general "NEVER USE EVER" overtones that surround `$_SERVER['HTTP_REFERER']`. Thanks. – kittykittybangbang Aug 30 '15 at 01:41
  • The `Referer:` header itself doesn't have anything to do with security. Now you can misuse it as additional ("security by obscurity") check. But that's not its purpose. It's an entirely informative/decorative browser info. It's perfectly fine for a lazy breadcrumb / previous page feature or something. – mario Aug 30 '15 at 01:43
  • @Dagon Sorry if I'm being thick, but is it really much different than using JavaScript in your web page, even though a user can choose not to run it? What's the difference? – kittykittybangbang Aug 30 '15 at 01:43
  • @kittykittybangbang I don't think I've ever heard to never ever *use* user-supplied information. That would be absurd. However, you should never ever *trust* user-supplied information. – Mike Aug 30 '15 at 01:45
  • @Mike That's what I'm saying -- but I've heard it suggested (by well-reputed users on SO, e.g.) that `$_SERVER['HTTP_REFERER']` should NOT be used. Period. ...Just wanted to know if there was something else about it that makes it suspect that I was unaware of. – kittykittybangbang Aug 30 '15 at 01:49
  • 2
    never TRUST and never USE are not the same thing. ALL user input cant be trusted, but it needs to be used –  Aug 30 '15 at 01:53
  • @Dagon I hope it's clear that I meant no offense in referencing your recent comment. I don't mean to contend with you -- I just want to understand the reasoning behind it. – kittykittybangbang Aug 30 '15 at 02:07
  • love a good spirited debate @kittykittybangbang - all good ;-) –  Aug 30 '15 at 02:54

1 Answers1

2

It can be a useful variable, but it shouldn't be relied on. Firstly, it isn't always provided (browsers can be set to not provide referrers), so code that relies on it may not work if it isn't provided.

Secondly, it is a rare situation where good security will trust even logged in users - just because they are logged in doesn't mean they aren't trying something they shouldn't.

Its fine to use it indicatively, but don't code with an assumption that its true...

Peter Badida
  • 11,310
  • 10
  • 44
  • 90
Lea de Groot
  • 309
  • 4
  • 12
  • "just because they are logged in doesnt mean they arent trying something they shouldnt." Valid point; but if each PHP file is written such that it checks user privileges each time it runs... doesn't that solve the security question? – kittykittybangbang Aug 30 '15 at 01:26