如何保护 ASP.NET Core Web API 免受被盗 JWT 令牌以进行模拟

Posted

技术标签:

【中文标题】如何保护 ASP.NET Core Web API 免受被盗 JWT 令牌以进行模拟【英文标题】:How to secure ASP.NET Core Web API from stolen JWT token for Impersonation 【发布时间】:2019-05-29 08:07:29 【问题描述】:

我在 IIS 后面的服务器中部署了一个 ASP.NET 核心 REST API。 REST API 由 Angular JS Web 应用程序和移动(android/ios)应用程序使用。对于授权,我使用的是 JWT token()。最近通过安全审计,他们发现存储在本地存储中的 JWT 可以被同一组织的其他攻击者窃取并用于冒充(例如,员工利用经理的功能)。

我想将这个人或那台机器标记到那个 JWT 上,这样当 JWT 被盗时,攻击者就不能滥用它或者不会对那个被盗的 Token 进行任何使用。我尝试使用 JWT 令牌标记 IP 并将这些查找存储在服务器中(在内存缓存中)。下面是我试过的代码,没用。

private readonly IHttpContextAccessor _httpContextAccessor;
public TestController(IHttpContextAccessor httpContextAccessor)

    _httpContextAccessor = httpContextAccessor;

var ipAddress = _httpContextAccessor.HttpContext.Connection.RemoteIpAddress.ToString();

我希望每次我从不同的机器请求时输出都会有所不同。但是每次像 15.11.101.25 这样的实际输出都是相同的 IP(尽管我从不同的机器上尝试过)。如果有的话,请与我分享一些更好的解决方案。请原谅我的英语。

【问题讨论】:

好吧,如果您使用代理或公共互联网连接,那么所有 IP 都相同是正常的。您应该从移动设备(未通过 WLAN 连接)尝试。另外,被盗代币与 CSRF 有什么关系? CSRF 发生在攻击者伪造链接(或页面上的表单并引诱您访问它,因此发送隐藏表单)时。使用 JWT 就不会发生这种情况,CSRF 仅容易受到 Cookie 身份验证,因为浏览器会自动将 cookie 与请求一起发送,而 JWT 不会发生这种情况 CSRF 无法从本地存储中获取令牌,这只能通过 XSS(跨站点脚本)实现,当有人设法将一段 javascript 代码注入您的网站时(当您没有正确清理您的用户输入)。此外,员工获得经理 JWT 令牌的情况也不太可能,除非 a)他们可以物理访问经理计算机(然后您的公司有其他更大的问题)或 b)用户可以将 javascript 代码注入网站并让经理打开它,在这种情况下,您与员工之间存在严重的信任问题 @Tseng 我们可以从移动设备尝试。但问题是它也应该适用于 Web。很抱歉将这个问题转移到 CSRF。主要问题是我应该避免用户 B 窃取用户 A 的令牌,这样用户 B 就不能冒充用户 A。 我的意思是,如果同一家公司的所有用户都有相同的IP(他们通过一个互联网连接共享相同的公共IP),使用IP作为鉴别器是没有意义的 @Tseng :我向我们的安全专家提到了完全相同的事情(“员工不太可能获得经理 JWT 令牌,除非他们可以物理访问经理的计算机)。但他们还没有准备好听. 所以需要找到一些解决方案来标记它。他们希望这个应用程序表现得像传统的会话概念。就像每个会话都是不同的,一个人不能窃取其他会话。为了争论,如果黑客攻击应用程序,我仍然可以争论设法获得了 Session cookie。但安全团队还没有准备好进行任何辩论。 【参考方案1】:

如果您真的需要这种安全性,您可以将 JWT 令牌与安全(=cookies 只允许通过 https 发送)http-only cookie 结合起来,并在其中存储一种请求令牌,在每个请求。

您可以阅读 Where to Store your JWTs – Cookies vs html5 Web Storage,其中涵盖了该主题,并解释了 JWT 本地存储与 cookie 的优缺点。

仅 Http cookie 无法通过 JavaScript 读取(因此不会被盗),因此可以抵御 XSS 攻击。基于 CSRF 的攻击无法获取 JWT 令牌(因为它是通过标头发送的)。

因此,基于 XSS 的攻击将没有基于 cookie 的令牌,而基于 CSRF 的请求将没有验证用户所需的 JWT 令牌。 cookie 令牌可以在登录时生成,因此它与登录该计算机的用户相关联。

你当然也可以把它转过来,把 JWT 放在一个安全的 cookie 中,把反请求令牌作为标头。

当然,您仍然可以通过物理访问机器来窃取防伪 cookie,但这既不是 XSS 也不是 CSRF,并且不能仅由应用程序保护,机器本身需要保护免受物理类型的攻击.

或者,不要将 JWT 令牌存储在本地存储中。当您使用 OpenID 流程时,您的应用程序将在第一次加载时看到它未授权,会将您重定向到 OpenID 提供程序,让用户输入他的凭据并使用令牌(或身份验证代码的代码)将其重定向回流)。

当用户关闭浏览器并再次打开站点时,不再有令牌,用户将被重定向到 OpenID 提供程序。由于用户仍处于登录状态,因此不会询问任何凭据,他将被重定向回他来自的页面,包括一组新的令牌。您只需要将令牌存储在内存中(并在过期时刷新)以用于当前应用程序会话。

【讨论】:

以上是关于如何保护 ASP.NET Core Web API 免受被盗 JWT 令牌以进行模拟的主要内容,如果未能解决你的问题,请参考以下文章

使用 MSAL 保护 ASP.Net Core Web API 和 Angular App

我应该如何保护我的 Web 应用程序(ASP.Net Core 3.1 MVC)?

壹刊Azure AD调用受Microsoft 标识平台保护的 ASP.NET Core Web API (上)

保护我方Id | ASP.NET Core Web API使用加密Id

保护我方Id | ASP.NET Core Web API使用加密Id

保护我方Id | ASP.NET Core Web API使用加密Id