通常使用以下方法之一来防止跨站请求伪造(CSRF):
- 检查引荐来源-RESTful但不可靠
- 将令牌插入表单并将令牌存储在服务器会话中-并非真正的RESTful
- 神秘的一次URI-出于与令牌相同的原因而不是RESTful
- 手动发送此请求的密码(不是HTTP身份验证使用的缓存密码)-RESTful但不方便
我的想法是使用用户机密,一个隐秘但静态的表单ID和JavaScript来生成令牌。
<form method="POST" action="/someresource" id="7099879082361234103">
<input type="hidden" name="token" value="generateToken(...)">
...
</form>
GET /usersecret/john_doe
由JavaScript从已验证的用户获取。- 回应:
OK 89070135420357234586534346
这个秘密从概念上讲是静态的,但是每天/每小时都可以更改……以提高安全性。这是唯一的机密内容。 - 使用JavaScript读取神秘的(但对所有用户而言都是静态的!)表单ID,并与用户密码一起处理:
generateToken(7099879082361234103, 89070135420357234586534346)
- 将表单以及生成的令牌发送到服务器。
- 由于服务器知道用户密码和表单ID,因此可以与客户端在发送并比较两个结果之前运行相同的generateToken函数。仅当两个值相等时,该操作才被授权。
尽管事实上如果没有JavaScript也无法使用,这种方法有什么问题吗?
附录: