[英]Do I need a CSRF token for jQuery .ajax()?
所以我有一个基本的 .ajax() POST 方法到 PHP 文件。
我需要什么安全措施?
一些帖子提到使用隐藏的 MD5 输入字段,您通过 AJAX 发送并在 PHP 文件中验证。 这是一个足够好的方法吗?
CSRF 的风险在于外部站点可能会将数据发送到您的站点,并且用户浏览器将自动发送身份验证 cookie。
您需要的是接收操作(您的$.ajax()
方法正在向其发送 POST 数据)的某种方式,以便能够检查请求是否来自您站点上的另一个页面,而不是外部站点。
有几种方法可以做到这一点,但推荐的方法是向请求添加一个令牌,您可以检查该令牌并且黑客无法访问该令牌。
最简单的:
$.ajax()
请求添加一个参数。黑客无法访问您的数据库,也无法实际读取您发送给用户的页面(除非他们受到 XSS 攻击,但这是另一个问题),因此无法欺骗令牌。
令牌的重要之处在于您可以预测(和验证)它而黑客不能。
出于这个原因,最容易生成长而随机的内容并将其存储在数据库中,但您可以构建一些加密的内容。 不过,我不会只对用户名进行 MD5 处理 - 如果 CSRF 攻击者弄清楚如何生成您的令牌,您将被黑客入侵。
另一种方法是将令牌存储在 cookie(而不是您的数据库)中,因为攻击者无法读取或更改您的 cookie,只会导致它们被重新发送。 那么你就是 HTTP POST 数据中的令牌匹配 cookie 中的令牌。
您可以使这些更加复杂,例如每次成功使用时都会更改的令牌(防止重新提交)或特定于用户和操作的令牌,但这是基本模式。
严格来说,不需要令牌,但您仍然应该保护任何更改状态的函数免受 CSRF 的影响。
CRSF 绝对是一种风险,即使请求是通过 AJAX 发出的。 这是因为 AJAX 请求可以跨域传递 - 同源策略仅防止读取,而不是写入。 而且,传统表单可能能够发送与 AJAX 完全相同的 POST 请求,而您当前的服务器端代码可能无法检测到这一点。
允许服务器端代码检测请求是否来自您自己的站点的一种简单方法是添加与 AJAX 请求一起发送的标头。 您的服务器端代码检查此标头是否存在非常重要。 不一定需要随机令牌。
这是有效的,因为:
为了防御网络上的任何未来发展,实现随机令牌可能是一个好主意。 这需要以某种方式与当前用户会话相关联。 如果没有实现令牌,它目前是不可利用的,但在网络漫长而曲折的历史中,缺少令牌可能会被 Flash 和其他浏览器插件利用。 在一个完美的世界中,HTML5 和生活标准应该意味着像这样的插件已经成为过去,但是,谁知道即将到来的事情是什么,所以为了增加深度防御和未来证明,令牌也是受到推崇的。
在请求伪造方面,客户端如何发送请求并不重要,重要的是它如何接收。 与任何其他类型的帖子一样,相同的 CSRF 规则适用于 ajax 帖子。
我建议阅读CSRF 预防备忘单。 使用每个用户的秘密令牌是最常见的保护形式。
这是您可以使用 django 尝试的简单演示:
在 HTML 页面上
{%block content%}
<form id="userForm">
{%csrf_token%}
<input type="text" id="username" placeholder="User Name">
<input type="password" id="password" placeholder="Password">
</form>
{%endblock%}
Java 脚本代码
%(document).on('submit','#userForm',function(e){
e.preventDefault();
$.ajax({
type = 'POST',
url:'path/to/url',
data:{
username:$('#username').val(),
password:$('#password').val(),
csrfmiddlewaretoken:$('input[name=csrfmiddlewaretoken').val()
},
success:function(data){
alert('Successfull');
}
});
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.