对于 REST-api,检查自定义标头的存在似乎足以防止 CSRF 攻击,例如客户端发送
“X-请求者:随便”
并且服务器检查“X-Requested-By”是否存在,如果找不到标头则丢弃请求。标头的值无关紧要。这就是 Jersey 1.9 的 CsrfProtectionFilter 的工作原理,并在此博客文章中进行了描述:http: //blog.alutam.com/2011/09/14/jersey-and-cross-site-request-forgery-csrf/。该博客文章还链接到 NSA 和斯坦福大学的论文,指出自定义标头本身就足够保护:
第一种方法涉及为每个 REST 请求设置自定义标头,例如 X-XSRF-Header。这个头的值无关紧要;简单地说,存在应该可以防止 CSRF 攻击。如果请求进入没有自定义标头的 REST 端点,则应丢弃该请求。
通过表单、图像、iframe 等执行的来自 Web 浏览器的 HTTP 请求无法设置自定义 HTTP 标头。从具有自定义 HTTP 标头的浏览器创建 HTTP 请求的唯一方法是使用诸如 Javascript XMLHttpRequest 或 Flash 之类的技术。这些技术可以设置自定义 HTTP 标头,但内置安全策略以防止网站相互发送请求,除非策略特别允许。这意味着网站 www.bad.com 无法向http://bank.example.com发送请求使用自定义标头 X-XSRFHeader,除非他们使用 XMLHttpRequest 之类的技术。除非 bank.example.com 域特别允许,否则该技术将阻止发出此类请求。这会产生一个只能通过 XMLHttpRequest(或类似技术)调用的 REST 端点。
请务必注意,此方法还可以防止从 Web 浏览器直接访问该 REST 端点。使用这种方法的 Web 应用程序需要通过 XMLHttpRequest 或类似技术与其 REST 端点进行交互。
来源:实施 REST 的指南
然而,似乎大多数其他方法都建议您生成一个令牌并在服务器上对其进行验证。这是过度工程吗?什么时候“存在”方法是安全的,什么时候还需要令牌验证?