【问题标题】:ASP.NET Core WebAPI Security ConsiderationsASP.NET Core WebAPI 安全注意事项
【发布时间】:2017-05-18 06:33:48
【问题描述】:

我的 WebAPI 就是供我的 UI 使用的 API 后端。事实上,我的 UI 可能会使用 10 种 WebAPI 服务。

我很难理解在安全方面我需要考虑什么。

我的 API 使用 Bearer 令牌进行保护,并且仅允许 https。我设置了 CORS,他们只允许来源 https://my-front.end 这一切都很好。

但是.. 如何防止 C/XSRF 和对 WebAPI 的重放攻击?我还需要吗?

使用 ASP.NET MVC 项目设置 anti-CSRF 相当轻松,但是如何在 WebAPI 上做到这一点,据我了解,它依赖于发送信息,在服务器上生成,然后发送到客户端在请求的正文中并通过另一个渠道(例如 cookie 或标头)。我读到您可以通过使用随机数(例如时间戳和随机数)来防止重放攻击——以某种方式——但找不到任何实现示例。

还有什么我需要考虑的吗?


编辑:前端使用 vue.js,但我们有一个非常称职的 JS 程序员,所以任何前端实现都不会成为问题。这只是找出什么需要做的事情!

还值得注意的是,为了一目了然,WebAPI 和 FrontEnd 在不同的服务器上运行,所以这些实际上都是跨源调用。

【问题讨论】:

  • 你在前端使用 Angular 之类的东西吗?您能否将此添加到您的问题中,因为 Angular 具有 CSRF 令牌等的默认设置。
  • 不,它是 vue.js,我已经适当地编辑了这个问题。 @MindingData
  • 确定一秒。只是为你解决:)

标签: javascript c# asp.net-core asp.net-core-webapi


【解决方案1】:

好吧。首先,您需要在标头中发送 XSRF 令牌。为此,您需要转到您的 ConfigureServices 方法并设置 AntiForgery 服务以接收此标头。

public void ConfigureServices(IServiceCollection services)
{
    services.AddAntiforgery(x => x.HeaderName = "X-XSRF-TOKEN");
    services.AddMvc();
}

接下来您需要生成令牌。由于前端和 API 是不同的服务,因此您需要在执行此操作时进行调整。例如,您可以在登录时执行此操作,或者您可以有一个专用端点执行此操作,但最终结果是相同的。

您可以在标头或 cookie 中返回令牌值,这取决于您。在我的示例中,我使用了 Cookie,稍后我将对其进行解释,但如果您愿意,也可以使用标题。

public class HomeController : Controller
{
    private readonly IAntiforgery _antiForgeryService;

    public HomeController(IAntiforgery antiForgeryService)
    {
        _antiForgeryService = antiForgeryService;
    }

    public IActionResult GetToken()
    {
        var token = _antiForgeryService.GetTokens(HttpContext).RequestToken;
        HttpContext.Response.Cookies.Append("XSRF-TOKEN", token, new CookieOptions { HttpOnly = false });
        return new StatusCodeResult(StatusCodes.Status200OK);
    }
}

IAntiforgery 服务应该已经可以使用(它是您将在 .net 核心服务中使用的“AddMVC”调用的一部分)。

好的,现在我们返回了一个带有令牌值的 cookie。现在我们只需要能够将其发送回去。

这是一些 jQuery 做的工作

<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/js-cookie/2.1.4/js.cookie.min.js"></script>
<script type="text/javascript">
    var token = Cookies.get("XSRF-TOKEN");

    $.ajax({
        url: "/",
        contentType: "application/json",
        type: "POST",
        headers: {
            "X-XSRF-TOKEN": token
        }
    });
</script>

现在需要注意的是 AngularJS 会自动执行此操作。使用 $http 时,它会查找名为“XSRF-TOKEN”的 cookie,然后自动将其作为标头发送。因为您使用的是 Vue,所以无论如何您基本上都会这样做,但更多的是手动过程。

同样重要的是要注意,不要将其设置为期望 cookie 作为 CSRF 令牌返回。否则无论如何,你已经打败了 CSRF 的全部目的。

然后您可以继续使用 AntiForgery 属性装饰您的操作/控制器。

[AutoValidateAntiforgeryToken]
public class HomeController : Controller
{

总之,它基本上归结为:

  • 设置 .net Core AntiForgery 以期望用于 CSRF 令牌的标头值
  • 有一个端点,它将手动生成一个令牌供您使用并将其作为 cookie/header 返回
  • 让您的前端读取此值并将其存储以供后续请求使用
  • 在后续请求中,将令牌值作为标头发送(不是 cookie)

大部分取自这里:http://dotnetcoretutorials.com/2017/05/18/csrf-tokens-angularjsjquery-asp-net-core/

【讨论】:

  • 非常感谢!在接下来的几天里,我将尝试这样做。我需要阅读有关如何进行 CSRF 攻击以更好地理解这一点,我觉得奇怪的部分是手动请求令牌,而不是让服务器将其烘焙到表单中。在提出愚蠢的问题之前,我可能最好先阅读:)
  • 实际上,如果您不使用 SPA (dotnetcoretutorials.com/2017/05/17/csrf-tokens-asp-net-core),以表格形式烘焙是正常的方式。但是在构建表单时,您需要使用 Razor HTML 帮助程序。您“可以”仍然将其作为隐藏字段放在表单上,​​但如果您使用的是 SPA,这没有任何意义。
  • 是的,有道理!如果我的所有端点都使用承载身份验证 (oidc) 进行保护,我需要担心这个吗?令牌被附加到我们的 js 应用程序中的请求 - 因此,如果用户被发送到试图调用 our.api/protected/endpoint 的狡猾站点,它就不会做任何事情,因为不会附加身份验证令牌?
  • 那是正确的。 CSRF 基于浏览器“存储”并随每个请求发送的内容。例如向该站点发送的每个请求都会发送一个 cookie。
  • 提醒一下,虽然上面的教程很棒,但让我失望的是获取 XSRF 令牌并将其保存为 cookie。而不是使用 _antiForgeryService.GetTokens(HttpContext).RequestToken;最好使用 _antiForgeryService.GetAndStoreTokens(HttpContext) 代替,因为这也会返回 & 自动创建并存储 AspNet.AntiForgeryToken cookie,即使您将 XSRF 令牌正确放入标题中,您也需要避免始终返回 400您的要求。
猜你喜欢
  • 1970-01-01
  • 2014-08-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多