当前位置: 首页 > 知识库问答 >
问题:

使用CSRF保护测试scala Play(2.2.1)控制器

子车文康
2023-03-14

我在测试使用Play的CSRF保护的控制器时遇到了一些问题。为了演示这一点,我创建了一个非常简单的Play应用程序,它可以将问题最小化。

https://github.com/adamnfish/csrftest

完整的详细信息在该存储库的自述中,但在此进行总结:

考虑设计用于处理表单提交的控制器。它有一个使用CSRFAddToken的GET方法和一个使用CSRFCheck的POST方法。前者向请求中添加一个CSRF令牌,以便在呈现视图中放置一个表单字段,其中包含有效令牌。提交该表单时,如果CSRF检查通过并且提交有效,则会发生其他情况(通常是重定向)。如果表单提交无效,表单提交将与任何错误一起重新显示,以便用户可以更正表单并再次提交。

这很有效!

然而,在测试中,我们现在有一些问题。要测试控制器,您可以在测试中向其传递假请求。通过向假请求添加nocheck头,可以跳过CSRF检查本身,但无法呈现视图,因为没有可用于生成表单字段的标记。测试失败,出现RuntimeException,“缺少CSRF令牌(CSRF.scala:51)”。

鉴于它在实际运行时有效,但在测试中无效,这似乎肯定是在Play测试中运行FakeRequest的方式有问题,但我可能做错了什么。我已经实现了http://www.playframework.com/documentation/2.2.1/ScalaCsrf中描述的CSRF保护和http://www.playframework.com/documentation/2.2.1/ScalaFunctionalTest.中描述的测试,如果有人设法测试了CSRF保护的表单,我将不胜感激。

共有3个答案

施锋
2023-03-14

继@plade之后,我在我的基本测试类中添加了一个helper方法

protected static FakeRequest csrfRequest(String method, String url) {
    String token = CSRFFilter.apply$default$5().generateToken();
    return fakeRequest(method, url + "?csrfToken=" + token)
        .withSession(CSRF.TokenName(), token);
}
闾丘高峰
2023-03-14

对于那些对Java感兴趣的人来说,一个额外的答案是:我通过添加

.withSession(CSRF.TokenName(), CSRFFilter.apply$default$5().generateToken())

到fakeRequest()

祁博涛
2023-03-14

一种解决方案是使用浏览器进行测试,例如Fluentlenium,因为这将管理cookie等,因此CSRF保护应该都可以工作。

另一种解决方案是向FakeRequest添加一个会话,以便它包含一个令牌,例如:

FakeRequest().withSession("csrfToken" -> CSRF.SignedTokenProvider.generateToken)

显然,如果您经常这样做,您可以创建一个帮助方法来帮助您。

 类似资料:
  • 在发送请求之前(当单元测试时),我是否可以得到csrf令牌?

  • 有人能给我提供一个代码示例来编写用HTTPS保护的控制器的联调吗??使用HTTP我可以编写,但使用HTTPS我得到了认证错误。 控制器 测试类别 错误 提前感谢

  • CSRF是指针对Web应用程序的跨站点伪造攻击。 CSRF攻击是系统的经过身份验证的用户执行的未授权活动。 因此,许多Web应用程序容易受到这些攻击。 Laravel以下列方式提供CSRF保护 - Laravel包含一个内置的CSRF插件,可为每个活动用户会话生成令牌。 这些令牌验证相关的经过身份验证的用户是否发送了操作或请求。 实现 (Implementation) 本节将详细讨论Laravel

  • 简介 Laravel 可以轻松地保护应用程序免受 跨站点请求伪造 (CSRF) 攻击,跨站点请求伪造是一种恶意攻击,它凭借已通过身份验证的用户身份来运行未经过授权的命令。 Laravel 会自动为每个活跃用户的会话生成一个 CSRF「令牌」。该令牌用于验证经过身份验证的用户是否是向应用程序发出请求的用户。 无论何时,当您在应用程序中定义HTML表单时,都应该在表单中包含一个隐藏的CSRF标记字段,

  • 有没有办法只使用spring security实现CSRF保护,而不使用身份验证和授权等其他功能? 我尝试了以下配置,但它关闭了spring security的所有功能。想知道是否有一种方法可以配置csrf功能。

  • 我目前添加了一个CSRF令牌保护机制到我的php应用程序。正如我所读到的,唯一的要求是一个独特的每个用户令牌,我在php7中使用random_bytes生成。 我担心的是,如果攻击者使用用户的浏览器发送http请求,浏览器不会发送令牌的会话变量吗?(因为用户具有与令牌关联的sessionid)。 我将令牌存储在会话变量的一个隐藏值内。 例如:我的令牌存储在会话变量中,然后攻击者将我发送到具有csr