I am building an ajax/PHP script and I have come up with something to protect the ajax file from external access, by that I mean to restrict the execution of the script from another server (and domain). I am using JQuery $ajax to post to the PHP file.
Here is the PHP file:
<?php
$config["url"]="mysite.com";
if (isset($_SERVER["HTTP_REFERER"])) {
$url = parse_url($_SERVER["HTTP_REFERER"]);
if ($url["host"] != $config["url"]) {
echo "You don't have access to this file.";
exit;
} else {
//Run The script
}
}
?>
Basically what this script does is that it matches the Referer and the domain. The script will exit if it doesn’t match and will run if it does. So the script can be executed from only mysite.com and not from elsewhere.
I am not PHP / Javascript expert, so can anyone tell me if this is good or not and if it will fail under some conditions?
What this script is protecting against is a Cross Site Request Forgery or CSRF. Checking the referer is one of the two primary defenses against this attack. The only problem is if the site has any user generated content, then they can add something such as:
which will still execute it.
The second most common prevention method is using a CSRF token for ajax.
Here are two resources to read up on to find more about this attack:
Description: https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)
Prevention: https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)_Prevention_Cheat_Sheet
Edit:
A little clarification that may clear confusion on the subject.
Any user can forge the referer header, but this is irrelevant. The reason it doesn’t matter is that if they can forge the referer, they can just as easily make a legitimate request.
The important part here is ensuring that they cannot forge a request from any other user. This is the only aspect that matters and the only reason for checking the referer and protecting against CSRF attacks.