CSRF

CSRF 是跨站请求伪造(cross-site request forgery)的缩写;它也被称为 XSRF、一键攻击和会话劫持(session riding)。它涉及攻击者利用用户在浏览器中与某些站点建立的信任关系。攻击者通过代表用户向站点发送未经授权的命令来利用站点对用户的信任。

通常,攻击者会欺骗用户向目标站点发送请求。例如,攻击者可能能够让用户打开一个由攻击者控制的页面上的链接。这个链接可能会代表已认证用户执行某些操作,而用户对此一无所知。

考虑一个例子,用户已通过银行网站的身份验证。用户可能会被欺骗点击一个链接,该链接向其银行网站发送转账请求。由于用户已通过身份验证,银行网站会认为此交易是安全的。然而,拥有此恶意链接的攻击者将能够将转账定向到他们选择的账户。

此软件包旨在防止 Vapor 中的此类攻击。

进一步阅读

防止 CSRF 攻击

有几种方法可以防止此类漏洞。由于攻击利用了站点对某些用户的信任,因此大多数预防技术都会向每个请求添加身份验证信息。这样做有助于站点区分授权请求和未经授权的请求。

此软件包采取的方向是使用会话(sessions)。会话将持有一个密钥(secret)。该密钥将用于创建哈希令牌(hashed token)。令牌将在响应头中发送回客户端。令牌的有效期与会话的有效期相同。

例如,服务器将生成一个令牌,并在标头中设置 "csrf-token" 键,如下所示

response.headers.add(name: "csrf-token", value: "some-very-secret-token")

然后,客户端负责在其会话期间的每个请求中发送此键和令牌。

CSRF 中间件将保证三件事

  1. 存在会话
  2. 请求包含一个键(有许多键用于 CSRF 防御)
  3. 该键的令牌与会话持有的密钥匹配

如果任何这些条件失败,则 CSRF 中间件将抛出一个错误来描述问题。

在 Vapor 中使用 CSRF

以下内容提供了关于如何在您的站点上使用此软件包的说明。

用法

  1. 将 CSRF 添加到您的 Package.swift 文件中
dependencies: [
    ...,
   .package(url: "https://github.com/vapor-community/CSRF.git", from: "3.0.0")
]
  1. configure.swift (或您的路由组...)中添加 SessionsMiddlewareCSRF 中间件
app.middleware.use(app.sessions.middleware)
app.middleware.use(CSRF())

这将创建一个具有两个重要默认值的实例

您可以通过将您的首选值传递给此初始化器来定制 CSRF 上的任一属性。

  1. 创建令牌并在响应头中设置它
router.get("test-no-session") { request in
    let response = ...
    response.headers.add(name: "csrf-token", value: CSRF.createToken(from: request))
    return response
}

与 Leaf 和表单一起使用

为了将此软件包与 Leaf 结合使用以保护表单,提供了一个方便的标签

app.leaf.tags["csrfFormField"] = CSRFFormFieldTag()
<form method="post">

<input type="text" name="username">
<input type="text" name="password">
[…]

#csrfFormField()

<input type="submit" value="Login">
</form>