So I've got a basic .ajax() POST method to a PHP file.
因此,我为PHP文件提供了一个基本的.ajax() POST方法。
What security measures do I need?
我需要什么安全措施?
A few posts around were mentioning using a hidden MD5 input field that you send via AJAX and verify in the PHP file. Is this a good enough method?
有几篇文章提到使用一个隐藏的MD5输入字段,通过AJAX发送,并在PHP文件中进行验证。这是一个足够好的方法吗?
3 个解决方案
#1
35
The risk from CSRF is that an external site could send data to yours and the users browser will automatically send the authentication cookie along with it.
来自CSRF的风险是外部站点可以向您的用户发送数据,而用户浏览器将自动发送身份验证cookie。
What you need is some way for the receiving action (that your $.ajax()
method is sending POST data to) to be able to check that the request has come from another page on your site, rather than an external site.
您需要的是接收操作(您的$.ajax()方法正在向其发送POST数据)的某种方式,以便能够检查请求是否来自站点的另一个页面,而不是外部站点。
There are a couple of ways to do this, but the recommended way is to add a token to the request that you can check for and that the hackers can't get to.
有两种方法可以做到这一点,但是推荐的方法是向可以检查的请求添加一个令牌,而黑客无法访问这个令牌。
At its simplest:
在其最简单的:
- On log on create a long random string token and save it against the user.
- 在登录时创建一个长而随机的字符串令牌,并将其保存到用户。
- Add a parameter to the
$.ajax()
request that includes the token. - 向包含令牌的$.ajax()请求添加一个参数。
- On request check that the token matches the one that you have saved for the user.
- 在请求时,检查令牌是否与您为用户保存的令牌匹配。
- If the token doesn't match you have a CSRF hack.
- 如果令牌不匹配,则使用CSRF hack。
The hacker can't get to your DB and can't actually read the page you've sent to the user (unless they get an XSS attack in, but that's another problem) so can't spoof the token.
黑客无法访问您的数据库,也无法实际读取您发送给用户的页面(除非他们受到XSS攻击,但这是另一个问题),因此不能欺骗令牌。
All that matters with the token is that you can predict (and validate) it and that the hacker can't.
与令牌相关的是,您可以预测(并验证)它,而黑客不能。
For this reason it's easiest to generate something long and random and store it in the DB, but you could build up something encrypted instead. I wouldn't just MD5 the username though - if the CSRF attackers figure out how to generate your tokens you'll be hacked.
由于这个原因,生成一个长而随机的东西并将它存储在DB中是最容易的,但是您可以构建一个加密的东西。我不只是使用MD5的用户名——如果CSRF攻击者想出如何生成你的令牌,你就会被黑。
Another way is to store the token is in a cookie (rather than your database), as the attackers can't read or change your cookies, just cause them to be re-sent. Then you're the token in the HTTP POST data matches token in the cookie.
另一种方法是将令牌存储在cookie(而不是数据库)中,因为攻击者无法读取或更改您的cookie,只会导致它们被重新发送。然后,HTTP POST数据中的令牌与cookie中的令牌匹配。
You can make these a lot more sophisticated, for instance a token that changes every time it's successfully used (preventing resubmission) or a token specific to the user and action, but that's the basic pattern.
您可以使它们更加复杂,例如每次成功使用时都会更改的令牌(防止重新提交)或特定于用户和操作的令牌,但这是基本模式。
#2
2
In terms of request forgery, it doesn't matter how the client sends the request it matters how its received. The same CSRF rules apply for an ajax post as any other type of post.
在请求伪造方面,客户端如何发送请求并不重要,重要的是如何接收请求。与任何其他类型的post一样,CSRF规则也适用于ajax post。
I recommend reading the CSRF prevention cheat sheet. Using a per-user secret token is the most common form of protection.
我建议阅读CSRF预防小抄。使用每个用户的秘密令牌是最常见的保护形式。
#3
0
No token is needed, but you should still protect any functions that change state against CSRF.
不需要任何令牌,但是仍然应该保护针对CSRF更改状态的任何函数。
One simple way of doing this is adding a header that is sent with the AJAX request. No random token is needed.
一种简单的方法是添加一个与AJAX请求一起发送的头。不需要任何随机标记。
This works because:
这个作品,因为:
- HTML forms cannot have custom headers added to them by an attacker.
- HTML表单不能有由攻击者添加的自定义标题。
- Custom headers cannot be passed cross-domain without CORS being enabled.
- 在没有启用CORS的情况下,不能跨域传递自定义头部。
Of course the server-side code needs to ensure that the header is present before executing its action.
当然,服务器端代码需要确保头在执行操作之前存在。
More info: What's the point of the X-Requested-With header?
更多信息:x - requested标题的意义是什么?
#1
35
The risk from CSRF is that an external site could send data to yours and the users browser will automatically send the authentication cookie along with it.
来自CSRF的风险是外部站点可以向您的用户发送数据,而用户浏览器将自动发送身份验证cookie。
What you need is some way for the receiving action (that your $.ajax()
method is sending POST data to) to be able to check that the request has come from another page on your site, rather than an external site.
您需要的是接收操作(您的$.ajax()方法正在向其发送POST数据)的某种方式,以便能够检查请求是否来自站点的另一个页面,而不是外部站点。
There are a couple of ways to do this, but the recommended way is to add a token to the request that you can check for and that the hackers can't get to.
有两种方法可以做到这一点,但是推荐的方法是向可以检查的请求添加一个令牌,而黑客无法访问这个令牌。
At its simplest:
在其最简单的:
- On log on create a long random string token and save it against the user.
- 在登录时创建一个长而随机的字符串令牌,并将其保存到用户。
- Add a parameter to the
$.ajax()
request that includes the token. - 向包含令牌的$.ajax()请求添加一个参数。
- On request check that the token matches the one that you have saved for the user.
- 在请求时,检查令牌是否与您为用户保存的令牌匹配。
- If the token doesn't match you have a CSRF hack.
- 如果令牌不匹配,则使用CSRF hack。
The hacker can't get to your DB and can't actually read the page you've sent to the user (unless they get an XSS attack in, but that's another problem) so can't spoof the token.
黑客无法访问您的数据库,也无法实际读取您发送给用户的页面(除非他们受到XSS攻击,但这是另一个问题),因此不能欺骗令牌。
All that matters with the token is that you can predict (and validate) it and that the hacker can't.
与令牌相关的是,您可以预测(并验证)它,而黑客不能。
For this reason it's easiest to generate something long and random and store it in the DB, but you could build up something encrypted instead. I wouldn't just MD5 the username though - if the CSRF attackers figure out how to generate your tokens you'll be hacked.
由于这个原因,生成一个长而随机的东西并将它存储在DB中是最容易的,但是您可以构建一个加密的东西。我不只是使用MD5的用户名——如果CSRF攻击者想出如何生成你的令牌,你就会被黑。
Another way is to store the token is in a cookie (rather than your database), as the attackers can't read or change your cookies, just cause them to be re-sent. Then you're the token in the HTTP POST data matches token in the cookie.
另一种方法是将令牌存储在cookie(而不是数据库)中,因为攻击者无法读取或更改您的cookie,只会导致它们被重新发送。然后,HTTP POST数据中的令牌与cookie中的令牌匹配。
You can make these a lot more sophisticated, for instance a token that changes every time it's successfully used (preventing resubmission) or a token specific to the user and action, but that's the basic pattern.
您可以使它们更加复杂,例如每次成功使用时都会更改的令牌(防止重新提交)或特定于用户和操作的令牌,但这是基本模式。
#2
2
In terms of request forgery, it doesn't matter how the client sends the request it matters how its received. The same CSRF rules apply for an ajax post as any other type of post.
在请求伪造方面,客户端如何发送请求并不重要,重要的是如何接收请求。与任何其他类型的post一样,CSRF规则也适用于ajax post。
I recommend reading the CSRF prevention cheat sheet. Using a per-user secret token is the most common form of protection.
我建议阅读CSRF预防小抄。使用每个用户的秘密令牌是最常见的保护形式。
#3
0
No token is needed, but you should still protect any functions that change state against CSRF.
不需要任何令牌,但是仍然应该保护针对CSRF更改状态的任何函数。
One simple way of doing this is adding a header that is sent with the AJAX request. No random token is needed.
一种简单的方法是添加一个与AJAX请求一起发送的头。不需要任何随机标记。
This works because:
这个作品,因为:
- HTML forms cannot have custom headers added to them by an attacker.
- HTML表单不能有由攻击者添加的自定义标题。
- Custom headers cannot be passed cross-domain without CORS being enabled.
- 在没有启用CORS的情况下,不能跨域传递自定义头部。
Of course the server-side code needs to ensure that the header is present before executing its action.
当然,服务器端代码需要确保头在执行操作之前存在。
More info: What's the point of the X-Requested-With header?
更多信息:x - requested标题的意义是什么?