不记名令牌和 CSRF
Bearer tokens and CSRF
我们正在构建 3 个不同的应用程序 MVC 应用程序,API,具有 ASP.NET 核心的 SPA(不是 Angular)。此应用程序中的所有操作仅供授权用户使用。这就是我们使用 IdentityServer 保护它们的原因。
我们使用 cookie 来存储不记名令牌的值。我知道 cookie 的值会自动发送到服务器。但是因为它应该作为授权添加 header 浏览器不会自动完成。
这是否降低了 CSRF 攻击的可能性?或者 CSRF 是否仍然可以使用不记名令牌,我们是否仍需要添加 CSRF 令牌?
是的,您仍然需要 CSRF 令牌。
如果您的 SPA 或 MVC 应用程序将根据用户的 GET 或 POST 操作向您的 API 发送请求,您仍然需要 CSRF 令牌。
假设有人诱骗您的用户点击 link 触发您的 SPA 中的操作,或发布到您的 MVC 应用程序,应用程序将愉快地遵守并发送存储在 cookie 中的不记名令牌作为请求 header,就像用户在应用程序本身中单击 link 一样。
这就是 CSRF 的全部要点,攻击者会像用户在您的 Web 应用程序中调用操作一样制作请求。
如果我理解你是对的,MVC 和 SPA 都使用 Identity Server 对用户进行身份验证,并将令牌存储在主要用于访问 API 的 cookie 中。
一般来说,这里有两种情况:
您的 cookies HTTP only(无法在前端访问)。然后您将 cookie 发送到 MVC 和 SPA 服务器端,它们提取 cookie 并将请求进一步发送到 API。在这种情况下,您像往常一样容易受到 CSRF 的攻击,因为您确实使用 cookie 进行了有效的身份验证,因此针对 API 的令牌提取和不记名身份验证的发生完全基于自动 cookie 身份验证的结果。
Cookie 可在前端访问。在这种情况下,您可以使用 Javascript 读取它们并将经过身份验证的承载请求发送到 MVC 和 SPA 服务器端(以便进一步传递到 API)或直接发送到 API 使所有后端忽略 cookie 内容可能受到损害。
在这种情况下,您不容易受到 CSRF 的攻击(正如您指出的必须显式构建承载身份验证 header)。但是,您容易受到 XSS (cross site scripting): any code injected into your page using either security hole in data validation/sanitation or simply third party dependency can read cookies and re-send them to any server. This case is very much alike using local/session storage so any articles describing their vulnerabilities apply to your scenario as well (e.g here).
所以你必须在CSRF和XSS之间选择一个作为主要攻击方式。
CSRF 可以用 anti-forgery 令牌完全阻止,但如果你不这样做,攻击很容易组织。
XSS 在理论上很难在现代开发中完全防止,因为您使用了大量的第 3 方库(另一种 XSS 攻击向量 - 输入卫生通常不是什么大问题,因为大多数 MVC 框架都这样做默认为您 like ASP NET Core). However, you have a fair chance of avoiding it which makes this option a reasonable choice in many cases e.g. Auth0 recommends it。
我们正在构建 3 个不同的应用程序 MVC 应用程序,API,具有 ASP.NET 核心的 SPA(不是 Angular)。此应用程序中的所有操作仅供授权用户使用。这就是我们使用 IdentityServer 保护它们的原因。
我们使用 cookie 来存储不记名令牌的值。我知道 cookie 的值会自动发送到服务器。但是因为它应该作为授权添加 header 浏览器不会自动完成。
这是否降低了 CSRF 攻击的可能性?或者 CSRF 是否仍然可以使用不记名令牌,我们是否仍需要添加 CSRF 令牌?
是的,您仍然需要 CSRF 令牌。
如果您的 SPA 或 MVC 应用程序将根据用户的 GET 或 POST 操作向您的 API 发送请求,您仍然需要 CSRF 令牌。
假设有人诱骗您的用户点击 link 触发您的 SPA 中的操作,或发布到您的 MVC 应用程序,应用程序将愉快地遵守并发送存储在 cookie 中的不记名令牌作为请求 header,就像用户在应用程序本身中单击 link 一样。
这就是 CSRF 的全部要点,攻击者会像用户在您的 Web 应用程序中调用操作一样制作请求。
如果我理解你是对的,MVC 和 SPA 都使用 Identity Server 对用户进行身份验证,并将令牌存储在主要用于访问 API 的 cookie 中。
一般来说,这里有两种情况:
您的 cookies HTTP only(无法在前端访问)。然后您将 cookie 发送到 MVC 和 SPA 服务器端,它们提取 cookie 并将请求进一步发送到 API。在这种情况下,您像往常一样容易受到 CSRF 的攻击,因为您确实使用 cookie 进行了有效的身份验证,因此针对 API 的令牌提取和不记名身份验证的发生完全基于自动 cookie 身份验证的结果。
Cookie 可在前端访问。在这种情况下,您可以使用 Javascript 读取它们并将经过身份验证的承载请求发送到 MVC 和 SPA 服务器端(以便进一步传递到 API)或直接发送到 API 使所有后端忽略 cookie 内容可能受到损害。 在这种情况下,您不容易受到 CSRF 的攻击(正如您指出的必须显式构建承载身份验证 header)。但是,您容易受到 XSS (cross site scripting): any code injected into your page using either security hole in data validation/sanitation or simply third party dependency can read cookies and re-send them to any server. This case is very much alike using local/session storage so any articles describing their vulnerabilities apply to your scenario as well (e.g here).
所以你必须在CSRF和XSS之间选择一个作为主要攻击方式。
CSRF 可以用 anti-forgery 令牌完全阻止,但如果你不这样做,攻击很容易组织。
XSS 在理论上很难在现代开发中完全防止,因为您使用了大量的第 3 方库(另一种 XSS 攻击向量 - 输入卫生通常不是什么大问题,因为大多数 MVC 框架都这样做默认为您 like ASP NET Core). However, you have a fair chance of avoiding it which makes this option a reasonable choice in many cases e.g. Auth0 recommends it。