CSRF
是基于 HTTP(S) 的应用程序的主要安全问题。
从表面上看,大多数框架都会将
CSRF
令牌作为请求正文的一部分发送。然而,就我而言,由于几个原因,这有点不优雅;最重要的是,我不想弄乱传输层,它可能会以多种不同的格式发送 POST
请求,不一定都是 JSON
或 x-www-form-urlencoded
。
作为解决方案,我正在考虑一种侵入性较小的替代方案;特别是,我正在生成一个随机标头:一个随机标头名称(通用前缀),包含一个随机
CSRF
标记。
这是否存在任何安全(或其他类型)风险?
X-Requested-With
标头,然后检查此服务器端。许多框架(例如 JQuery)会自动将其添加到 AJAX 请求中。
X-Requested-With
是指示请求是通过 AJAX 发出的事实上的标准。
您不需要随机令牌,因为如果服务器没有通过 CORS 选择加入,则无法跨域发送此标头。
因此,设置和检查非标准标头是防范 CSRF 的有效方法。
OWASP CSRF 预防备忘单 没有提及它,但它确实提到检查
Origin
标头。然而,其逻辑并不简单,因为许多浏览器不会针对同源请求发送Origin
。
此外,这只适用于 AJAX 请求。对于普通形式的 POST,不可能添加额外的标头。此外,过去 Flash 等插件存在允许设置任何标头的错误,从而使攻击者能够使用 Flash 发出跨域请求。然而,此类问题早已得到修复。
如果您想要一个令牌以及深度防御策略的一部分,您可以调整
X-Requested-With
以包含一个随机令牌,然后进行检查。例如X-Requested-With: XMLHttpRequest;0123456789ABCDEF
。
那么令牌可以只是为了防止 CSRF 目的而创建的 cookie 值(当然是使用加密安全算法和熵源生成的)。
这是否存在任何安全(或其他类型)风险?
没有:只要您可以从客户端传递它并在服务器上检查 - 就可以了
另外,我应该多久刷新一次 CSRF 令牌?我是否需要为每个请求或每隔几个请求提供一个新的,或每次站点访问和每天一次,或者......?
一般来说你根本不应该刷新它。如果它是使用加密的强随机数生成器生成的 - 您可以在每个会话中使用一个。重要的是,不可能猜测它,因此它不应该从任何已知数据中得出。