如何防止跨域ajax请求?
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
没有任何绝对万无一失的方法可以防止这种情况,因为任何标头信息都可以被欺骗。基于会话的令牌是另一种可能的解决方案,但在这种情况下,您的 JavaScript 是可公开访问的,因此任何愿意花一点时间的人都可以确定您的令牌系统如何工作并找出解决方法。
多种方法的结合将为您提供最广泛的保护。您可以查找标头、使用 .htaccess 文件以及使用令牌。这种综合上述方法使得滥用网络服务器变得更加困难——大多数滥用行为来自于人们试图找到一个容易利用的漏洞。需要记住的重要一点是,您不能因为部署了“最好”的保护而自满,或者因为您拥有如此多的保护层而似乎无法破解。如果有人真的非常想要并且有时间,他们就会找到办法。这些类型的预防措施实际上只是起到威慑作用,阻止那些懒惰、好奇和恶意的人。有针对性的攻击是一个完全独立的安全类别,通常更集中于服务器级别的安全问题。
htaccess 示例。这不会是您放在根目录中的内容,而是放在子文件夹中,其中包含永远不应该从地址栏调用的脚本:
查看这篇文章以获取有关使用令牌系统的信息:https://www.owasp.org/index.php/Cross-Site_Request_Forgery_%28CSRF%29_Prevention_Cheat_Sheet
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:
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
您可以手动拒绝
Origin
标头与您的域名不匹配的每个请求。但是,并非所有浏览器都会发送Origin
标头。在这些情况下,您可以回退到Referer
[sic] 标头,对其进行解析并找出域名,然后按上述方式进行比较。一些 JavaScript 框架还为 AJAX 请求设置
X-Requested-With
标头。这应该会拒绝很大比例的用户(我估计> 95%)。请注意,由于 同源政策,发送 AJAX 请求的唯一对象无论如何,您的域获取的是计时信息。
You can manually deny every request whose
Origin
header does not match your domain name. However, not all browsers send theOrigin
header. In these cases, you can fallback to theReferer
[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.
有点像 user3491125 建议的那样,您可以在进行调用的页面中设置 $_SESSION ,并在 Ajax 调用的页面上检查它是否设置了 $_SESSION['user'] 等。
A bit like user3491125 proposed, you could set a $_SESSION in the page where the call is made and check it on the page Ajax called if there is for instance $_SESSION['user'] set.
对于user3491125的答案,您可以尝试加密会话令牌。我有一个加密功能,可以根据用户端口 80 IP 添加唯一密钥。这并不是万无一失的,但它确实让黑客变得更加困难。
for user3491125's answer, you could try encrypting the session token. I have one encryption function that can add a unique key based on a users port 80 IP. it's Not foolproof, but it does make it more difficult for hackers.
这不是一个可以解决的问题。如果您创建一个网站,根据定义,您就可以公开使用该网站。
如果您希望数据保密,则需要某种登录方式。
如果没有登录/烦人的验证码,就不可能创建一个对用户开放但对脚本不开放的系统。
This isn't a problem that can be solved. If you create a website you make it, by definition, openly available.
If you want your data to be private, you need to require some sort of login.
It is impossible to create a system that is open to users but not to scripts without login/annoying captchas.
我知道这是一篇旧帖子,但目前有一种“万无一失”的方法可以避免这种情况,而且它非常简单......
首先在将进行 ajax 调用的页面中:
然后在 ajax 脚本中
最后在将被调用的 php 页面中:
I know this is an old post but currently THERE IS a "foolproof" method to avoid this and its as simple as hell...
First in the page where the ajax call will be made:
Then in the ajax script
And finally in the php page that will be called: