跨站点请求伪造是在 Web 应用程序中发现的一个漏洞,它允许第三方攻击者代表用户执行敏感操作。该漏洞的利用可以针对普通用户和站点管理员,有时会导致网站完全受损。现代网站倾向于部署一些保护机制来抵御这种攻击。大多数保护机制是识别和拒绝来自不同网站的请求。
目前使用的保护方法有:
1. 反CSRF令牌
这是一个加密的强字符串,与 cookie 分开提交给网站。这可以作为请求参数或作为 HTTP 标头发送。服务器在发出请求时检查此令牌的存在和正确性,并且仅当令牌正确且 cookie 有效时才继续。
2. HTTP PUT 方法
PUT 方法用于在服务器上创建资源的实例。它类似于 POST,除了多次发送相同的 PUT 请求不会做任何额外的事情。如果服务器对敏感操作使用 PUT 方法,则该端点不需要任何额外的 CSRF 保护(除非启用了跨源资源共享)。这是因为 PUT 请求不能通过像 POST 请求这样的网页进行复制(HTTP 表单不允许 PUT 请求)。但是,如果端点配置错误的 CORS,XHR PUT 请求可以发送并且会成功。
3. HTTP 承载认证
这是一种 HTTP 身份验证,其中用户通过在每个请求的“授权”标头中提交的令牌进行识别。这种机制解决了 CSRF,因为与 cookie 不同,它不是由浏览器自动提交的。
这些方法中的每一种都存在问题和潜在的绕过方法。反 CSRF 令牌没有固定的标准,因此它们的生成机制和使用完全取决于开发人员的意图。由于缺乏标准,Web 应用程序中存在许多特定于实现的漏洞。
- 一些网站会检查 CSRF 令牌是否绑定到会话,但不验证令牌是否绑定到请求尝试访问的同一会话。
- 一些网站在标头/请求参数以及 cookie 中发送令牌,这些令牌在服务器端匹配。如果匹配成功,则允许操作。但是如果网站本身没有检查token的真实性,并且网站容易受到XSS攻击,则可以通过在请求参数/header中提供随机token并利用XSS漏洞放置与cookie相同的token来轻松绕过该机制.
- 如果端点的 CORS 配置错误,这也可以绕过。
- 如果网站容易受到 UI 修正(点击劫持)的影响,那么这种机制是没有用的。
HTTP PUT 方法对 XSS 是安全的,因为没有“令牌”可以泄漏。但是,如果该网站允许跨源资源共享并且没有正确配置,那么攻击者可以简单地通过 XHR 发送 PUT 请求来复制 PUT 请求。最常见的错误配置是将响应中的原始标头反映为“Access-Control-Allow-Origin”的值。除此之外,如果 CORS 请求允许 PUT 方法,那么可以通过向端点发送精心设计的 XHR 请求来轻松完成 CSRF 攻击。由于 HTML 表单可能允许某些即将发布的标准中的 PUT 请求。所以开发人员必须保持更新。
此外,错误配置的 PUT 方法可能允许将任意文件上传到服务器。
承载身份验证是防止 CSRF 的好方法,因为攻击者无法知道经过身份验证的用户的有效令牌的值。但有些网站同时使用 cookie 和不记名令牌作为身份验证机制。在没有令牌的情况下,他们可能会依赖 cookie 进行身份验证,这将使 Web 应用程序容易受到 CSRF 的攻击。
开发者在开发反 CSRF 机制时,应该时刻牢记这些——
1. 永远不要通过 GET 请求发送 CSRF 令牌。
2. 将令牌绑定到用户的会话并在会话过期后立即使其失效。
3. 不要使用可逆编码系统来创建 CSRF 令牌。
4. 如果您依赖 PUT 请求进行 CSRF 保护,则不允许跨域 PUT 请求。
5. 不要为用户的每个会话使用单个令牌。