如何解决如何防止跨域Ajax请求?
| 如何检测是否从另一个域调用了我的PHP脚本,并且另一个域正在非法使用我的脚本?有没有办法防止这种情况? 更新 我在SO上发现了这个问题,但它仍然不安全,可以被欺骗。解决方法
没有任何绝对安全的方法可以防止这种情况发生,因为可以欺骗任何标头信息。基于会话的令牌是另一种可能的解决方案,但是在这种情况下,您的javascript是可以公开访问的,因此任何想花一点时间的人都可以确定您的令牌系统的工作方式,并找到解决方案。
多种方法的组合将为您提供最广泛的保护。您可以查找标题,使用和.htaccess文件以及使用令牌。这种全面的方法使滥用Web服务器变得更加困难-大多数滥用来自试图找到容易利用的漏洞的人们。要记住的重要一点是,您不会因为已经部署了“最佳”保护措施而感到自满,或者因为您拥有太多保护层而似乎无法破解。如果有人真的想要它足够糟糕并有时间,他们会找到方法。这些类型的预防措施实际上只能阻止那些懒惰,好奇和无所事事的恶意软件。有针对性的攻击是一整套单独的安全性,通常更集中于服务器级安全性问题。
样本htaccess。这不是您要放在根目录中的内容,而是放在一个子文件夹中,该子文件夹中的脚本永远不应从地址栏中调用:
RewriteEngine on
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http(s)?://(www\\.)?_YOUR_DOMAIN_NAME_HERE.com [NC]
RewriteRule \\.(php)$ - [NC,F,L]
请查看此文章以获取有关使用令牌系统的信息:https://www.owasp.org/index.php/Cross-Site_Request_Forgery_%28CSRF%29_Prevention_Cheat_Sheet
, 您可以手动拒绝每个Origin
标头与您的域名不匹配的请求。但是,并非所有浏览器都发送Origin
标头。在这些情况下,您可以回退到Referer
[sic]标头,进行解析并找出域名,然后如上所述进行比较。
一些JavaScript框架还为AJAX请求设置了“ 4”头。
这应该会拒绝很大一部分用户(我估计> 95%)。请注意,由于“同源策略”,向您的域发送AJAX请求的家伙唯一获得的就是定时信息。
, 有点像建议的user3491125一样,您可以在进行调用的页面中设置$ _SESSION,并在Ajax页面上检查它,例如是否设置了$ _SESSION [\'user \']。
, 对于user3491125的答案,您可以尝试加密会话令牌。我有一个加密功能,可以基于用户端口80 IP添加唯一密钥。它并非万无一失,但确实使黑客更加困难。
function encryptString($string,$action,$baseIP = \'false\',$extraKey = \'\'){
global $flag;
$encryptedIP = \'\';
if($baseIP){
$encryptedIP = encryptString(strip_tags(htmlentities($_SERVER[\'REMOTE_ADDR\'])),\'encrypt\',false);
}
$output = false;
$encrypt_method = \"AES-256-CBC\";
$secret_key = $flag[\'encrypt-key\'].$encryptedIP.\'-\'.$extraKey;
$secret_iv = $flag[\'encrypt-secret\'].$encryptedIP.\'-\'.$extraKey;
$key = hash(\'sha256\',$secret_key);
$iv = substr(hash(\'sha256\',$secret_iv),16);
$output;
if($action == \'encrypt\'){
$output = openssl_encrypt($string,$encrypt_method,$key,$iv);
$output = base64_encode($output);
$output = str_replace(\'=\',\'[equal]\',$output);
}else if($action == \'decrypt\'){
$setString = str_replace(\'[equal]\',\'=\',$string);
$output = openssl_decrypt(base64_decode($setString),$iv);
}
return $output;
}
, 这不是可以解决的问题。如果您创建一个网站,那么根据定义,您将使其公开可用。
如果您希望数据是私有的,则需要进行某种登录。
如果没有登录/烦扰验证码,就不可能创建一个对用户开放但对脚本不开放的系统。
, 我知道这是一篇过时的文章,但目前这里有一种“万无一失”的方法来避免这种情况,并且它像地狱一样简单...
在将进行ajax调用的页面中的第一个:
<?php
$token = sha1(rand(1000,9999));
$_SESSION[\'token\'] = $token;
?>
然后在ajax脚本中
var formData = new FormData();
formData.append(\"token\",\"<?php echo $token;?>\");
$.ajax({
url: \'yourfile.php\',type: \'POST\',xhr: function() {
var myXhr = $.ajaxSettings.xhr();
return myXhr;
},success:function(data) {
alert(data);
},data: formData,cache: false,contentType: false,processData: false
});
最后在将被调用的php页面中:
<?php
$token = $_POST[\'token\'];
if($token === $_SESSION[\'token\'] && $_SERVER[\'HTTP_X_REQUESTED_WITH\'] == \'XMLHttpRequest\')
{
//Perform your stuff here...
}
?>
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。