How to prevent cross-domain ajax requests?
Solution 1
There isn't any absolutely foolproof method to prevent this, since any header information can be spoofed. Session-based tokens are another possible solution, but in that case your javascript is publicly accessible, so anyone who wanted to spend a little time could determine how your token system works and figure out a way around it.
A combination of methods will give you the most wide-ranging protection. You can look for the header, use and .htaccess file, and use tokens. This sort of all-of-the-above approach makes it that much harder to abuse a web server - most abuse comes from people trying to find an easy hole to exploit. The important thing to remember is that you can't become complacent because you've deployed "the best" protection, or because you've got so many layers of protection that it seems impossible to crack. If someone really wanted it bad enough and had the time, they'll find a way. These types of preventative measures are really only deterrents to keep away the lazy, curious, and idly malicious. Targeted attacks are a whole separate class of security, and usually are more centered on server-level security issues.
Sample htaccess. This would not be something you'd put in your root, but rather within a subfolder where you have scripts that should never be called from the address bar:
RewriteEngine on
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?_YOUR_DOMAIN_NAME_HERE.com [NC]
RewriteRule \.(php)$ - [NC,F,L]
Check out this article for info about using a token system: https://www.owasp.org/index.php/Cross-Site_Request_Forgery_%28CSRF%29_Prevention_Cheat_Sheet
Solution 2
You can manually deny every request whose Origin
header does not match your domain name. However, not all browsers send the Origin
header. In these cases, you can fallback to the Referer
[sic] header, parse it and find out the domain name, and compare it as above.
Some JavaScript frameworks also set an X-Requested-With
header for AJAX requests.
This should reject a significant percentage of users (I'd estimate >95%). Note that due to the Same-Origin Policy, the only thing the guy sending AJAX requests to your domain gets is timing information anyway.
![Sujit Agarwal](https://i.stack.imgur.com/77aGh.jpg?s=256&g=1)
Comments
-
Sujit Agarwal about 2 years
How can I detect if my php script is being called from another domain and the other domain is making illegal use of my script? Is there a way to prevent this too?
UPDATE
I found this question on SO, but its still not safe, it can be spoofed.
-
Marc B about 13 yearsUsing an access token is probably your best bet. Referers aren't reliable and easily forged.
-
Sujit Agarwal about 13 yearsOh, but i dont know how to implement a access token. Could you please show some light on it through an answer?
-
Marc B about 13 yearsSet a cookie of some sort of authorized users of the service. Check for this cookie on each invocation of the ajax handling script. Or embed the token in your script so its sent as a parameter on each AJAX call from your own legitimate code. Basically have SOMETHING sent along with the request to identify a legit user from one of the bandwidth thieves. If they get smart and copy the token, then only provide the token via a login mechanism or some other per-user identification system.
-
phihag about 13 yearspossible duplicate of How server can check ajax requests not from site, X-Requested-With
-
-
Sujit Agarwal about 13 yearsCheck the update. BTW, in your answer's case, if all browsers dont send the Origin header, then what else can be done?
-
Sujit Agarwal about 13 years` the only thing the guy sending AJAX requests to your domain gets is timing information anyway.` what do you mean by this?
-
phihag about 13 years@Coding Freak Updated with a detailled explanation and
X-Requested-With
. However, I've no idea why someone would send random AJAX requests. -
Sujit Agarwal about 13 yearsBecause recently i have been checking out in my logs that many XHR requests have been made from an outside server.
-
phihag about 13 years@Coding Freak The Same-Origin Policy prevents you from getting the results of an AJAX call to another domain, unless you explicitly opt in to Cross-Origin Resource Sharing. Therefore, I can't imagine the motivation somebody would have to send AJAX queries to your site.
-
phihag about 13 years@Coding Freak What do you mean with "made from an outside server"? XHR requests are usually made by the client. The Referer points to another site or what? Can you provide an example log entry?
-
Sujit Agarwal about 13 yearsSorry, a bit mistake, I didnt know, that my web server is enabled for Cross-Origin Resource sharing or not, but i have been observing a huge consumption of bandwidth on my server without that number of reasonable visits on my pages.
-
Chris Fremgen about 9 yearsThe problem here is rand() is not really random. It's a time based pseudo-random number. While this is still a preferred method, it's by no means "foolproof".
-
user3491125 about 9 yearsbut it has no impact since the string is stored on a session so only associated to this computer ;) thanks for informing anyway
-
aug over 8 yearsI think the answer on session spoofing helps with this in some ways but not sure if this is the ideal solution OP was looking for.
-
Chris Baker about 8 yearsThis is also not foolproof because the token is exposed in the script. If I were targeting an attack on this, I could use curl to load the page, parse the token out, then send the malicious request using a good token.
curl_setopt($ch, CURLOPT_HTTPHEADER, array("X-Requested-With: XMLHttpRequest"));
defeats the other measure, and curl doesn't care about the Same Origin Policy. As I said, there isn't really a silver bullet here.