跨站请求伪造(CSRF)通常用以下方法之一预防:如何在RESTful应用程序中防止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
这个秘密在概念上是静态的,但可以每天/每小时更改一次...以提高安全性。这是唯一保密的事情。 - 阅读所有用户的神秘(但对所有用户都是静态的!)form id,与用户秘密一起处理它:
generateToken(7099879082361234103, 89070135420357234586534346)
- 将表单连同生成的令牌一起发送到服务器。
- 由于服务器知道用户密码和表单ID,因此可以在发送和比较两个结果之前运行与客户端所做的相同的generateToken函数。只有当两个值相等时,动作才会被授权。
这种方法有什么问题,尽管它没有JavaScript没有用吗?
附录:
您的usersecret对用户来说并不是唯一的,攻击者只需要获取该数字并调整其脚本以使用新计算即可。如果你根本没有状态,你如何验证用户? – Mike 2010-03-06 10:19:42
用户密码对于每个用户都是唯一的,只能在认证后进行检索(HTTP基本或摘要认证或证书认证) – deamon 2010-03-07 08:27:50