0

I'm about to create a new website and am worried about potential security flaws. I'm focusing on the possibility of others using my PHP scripts (which, as far as I know, is possible with methods such as CORS or cURL -- am I wrong?).

I just searched around and found that you could use PHP's $_SERVER["HTTP_REFERER"] to check the URL from which it was sent.

There were a lot of questions out there on SO, such as this one and this one regarding the use and security of $_SERVER["HTTP_REFERER"].

Many of the answers are similar to this one (shown below) that say that it's not safe because software often strips it out:

It may be safe, but it is not reliable: due to the HTTP spec, HTTP_REFERER is optional (some clients don't send this header at all, and some "security" software strips this out from any HTTP request), and there are numerous ways to modify this header. Some browsers send the referring page, some send a blank string, some don't send this at all, some may send bogus data, some may send Aunt Matilda; and moreover, you can't tell whether you're getting valid data in this header or not.

So, no, I would never trust that HTTP_REFERER contains the previous page, and neither should you.

But they just mostly imply that the referer information may just be left out / missing / incomplete, but not wrong.

Therefore, would it be safe to use it like so:

<?php
    if($_SERVER["HTTP_REFERER"] != "my_http_referer.php") {
        die("You cannot access this script.");
    }
?>

Wouldn't this be safe, even if the $_SERVER["HTTP_REFERER"] is optional and may be incomplete? If it's any script other than my own that's calling this, shouldn't it die()? Or am I overlooking something?

Community
  • 1
  • 1
Jonathan Lam
  • 16,831
  • 17
  • 68
  • 94
  • I wouldn't be to worried about others using your PHP scripts. There's something known as the [Same Origin Policy](https://en.wikipedia.org/wiki/Same-origin_policy). Which basicly means that as long as you don't give explicit permission for it, no other domain or server can access your scripts. – icecub Nov 30 '15 at 03:15
  • @icecub But aren't there ways to circumvent the same-origin policy, such as with CORS or cURL (I'm not familiar with those technologies, so correct me if I'm wrong). There's even a whole [SO thread](http://stackoverflow.com/questions/3076414/ways-to-circumvent-the-same-origin-policy) regarding this. – Jonathan Lam Nov 30 '15 at 03:25
  • What kind of abuse are you trying to protect against? It's not clear why some users should be able to use the site and not others, and what would be a good method to ensure access is controlled. – Michael Curtis Nov 30 '15 at 03:34
  • I don't know to much about CORS or cURL myself. But I do know they are permission based. You have to explicitly allow the other origin in your script to access it before that origin can use CORS or cURL to access the script. This is why you can't email a form to someone for example. The server wouldn't accept the POST data coming from the email server (different origin). – icecub Nov 30 '15 at 03:36
  • @MichaelCurtis I don't mean attacks from *certain users*, I mean potential attackers from users at home who might input funky data into my PHP scripts and try to hack the site (maybe add info, maybe take info). But users (from the site itself) are not a problem. – Jonathan Lam Nov 30 '15 at 03:42
  • 1
    @Jonathan thanks for clarifying. So with those examples you probably want to be sure to not accept un-validated user input or pass it to potentially unsafe PHP functions like exec() or a database query that does not use prepared statements. A potential hacker trying those things can easily spoof the http referer. It's probably better to plug holes in the PHP scripts. – Michael Curtis Nov 30 '15 at 03:50

1 Answers1

1

If web app security is your primary concern, you should use some other mechanism to maje sure the request indeed came from your own other page. The answer you quoted is well explanatory. You shouldn't trust HTTP_REFERER only.

You can make use of sessionStorage if you want to set some other identifying token. And then read that each time you submit the form. Cross check it every time you receive the request. And you can keep on altering it if you want to have more non-predictive behavior.

Does that make sense?

Prabhas Gupte
  • 68
  • 2
  • 10
  • Yes, it makes sense, but I'm a little confused on how you could use `sessionStorage` (web storage). Isn't that unsafe? Even if you hash it, how would you know what value to check from the PHP? Could you go into a little more detail or provide an example please? – Jonathan Lam Nov 30 '15 at 03:18
  • 1
    First of all, I assume it will be a POST request. You could use javascript to read that value on each form submit, add it to your request params. You also need to have some weird logic to generate value for that, which you will use to cross check against valid sessions on server side. This way, each time your page is accessed in browser, may be for each new session, you set different value. Can you built up on top of this? I am on the go right now, so unable to quickly write an example for you. – Prabhas Gupte Nov 30 '15 at 03:33
  • I'll have to figure out that "weird logic" for myself, I guess, but thank you for the follow-up! – Jonathan Lam Nov 30 '15 at 03:41
  • Yes. Weird or non-obvious. – Prabhas Gupte Nov 30 '15 at 03:42
  • 1
    You can go for any reversible encryption or checksum or anything simple to implement. – Prabhas Gupte Nov 30 '15 at 03:43
  • It should be safe enough to implement. The site's nothing major, so thanks! – Jonathan Lam Nov 30 '15 at 03:45
  • 1
    The cUrl doesn't execute javascript. So that side will be taken care of. Even if anyone uses any other lib which can execute js, they don't know your logic! – Prabhas Gupte Nov 30 '15 at 03:45