所有文章 > 技术杂货铺 > Kotlin CSRF保护指南:示例和如何启用它
Kotlin CSRF保护指南:示例和如何启用它

Kotlin CSRF保护指南:示例和如何启用它

安全性一直是任何应用程序的一个非常重要的因素,我们这里只讨论软件。在系统计算机化之前,就有人试图绕过这些流程。随着技术的进步,我们现在可以随时使用应用程序,而且比以前更容易使用。

作为程序员,我们经常担心应用程序的可用性和性能,但确保数据在客户端和服务器之间安全传输也至关重要。在网络上,我们有几种形式的攻击和几种预防方法。在本文中,我们将重点介绍一种称为跨站点请求伪造 (CSRF)的特定攻击类型,并讨论一些示例和预防方法。为此,我们将使用 Kotlin 作为编程语言。

进一步

让我们从一个例子开始。

如果在应用程序中,我们有一个请求返回有关登录系统的用户的一些数据,则浏览器需要确保该请求具有相同的来源。这意味着网站可以自由地从其自己的 URL 请求数据,但会阻止来自外部 URL 的任何内容,除非我们在服务器端指定此权限。我们称之为同源策略。这可以防止外部网站请求他们不应该拥有的数据。

我们还针对任何请求发送 Cookie。应用需要一种方法来识别用户,而网络上识别用户的标准方法是使用 Cookie。例如,当用户登录社交媒体网站时,服务器会设置一个具有唯一用户 ID 的 Cookie。当用户浏览网站时,对服务器的每个请求都包含该 Cookie。

服务器可以从请求中读取 cookie 并加载用户特定的数据,例如用户的时间线或访问权限。

因此,我们使用在应用程序后端生成的随机令牌,并将它们发送到网站,以防止 CSRF 之类的攻击。

由于我们必须在每个请求中验证新令牌,因此恶意网站不能简单地将请求视为合法请求,因为它没有正确的令牌。

之后,您需要在应用程序中配置 Spring Security 的 CSRF 保护。我们使用此工具是因为它与 Kotlin 配合良好,并且已经有了大量文档。我们可以进行自定义,但我们已经默认启用了 CSRF 保护。

我们如何保护用户免受 CSRF 攻击?

通过使用 CSRF 保护,您想要确保只有 Web 应用程序的前端可以执行变异操作。

用户必须使用HTTP GET发送请求才能偶尔访问该页面。发生这种情况时,应用程序会生成一个唯一的令牌。应用程序认为,知道令牌的来源可以确认是应用程序本身发出了更改请求,而不是其他系统。

我们可以将 CSRF 保证的起点作为通道链中名为CsrfFilter 的通道。

CsrfFilter干预请求并允许所有使用这些 HTTP 方法的请求:GET、HEAD、TRACEOPTIONS 对于所有其他请求,过滤器需要获取包含令牌的标头。如果此标头不存在,应用程序将拒绝请求。CsrfFilter使用名为CsrfTokenRepository组件来管理创建现代令牌的 CSRF 令牌值。默认情况下,CsrfTokenRepository将令牌存储在 HTTP 会话中并将令牌创建为 UUID。

一个简单的例子

例如,我们考虑一个简单的登录表单,该表单需要用户名、密码和 CSRF 令牌。对于前端,我们只需在表单中包含 CSRF 令牌即可。

此示例可在Stone Soup Programming中找到。

一旦完成前端代码的开发,我们就想设计 Spring Security 来利用此页面。为了呈现登录页面,Spring 需要一些控制器类。

@Configuration
class WebConfig : WebMvcConfigurerAdapter() {
override fun addViewControllers(registry: ViewControllerRegistry) {
//Default controller for the login page.
registry.addViewController("/login").setViewName("login")
}
}

然后我们配置Spring Security:

@Configuration
@EnableWebSecurity //Turn on Web Security
class SecurityWebInitializer : WebSecurityConfigurerAdapter(){
override fun configure(http: HttpSecurity) {
http
.authorizeRequests()
//We need to allow anonymous users to
//access the login page (otherwise we get 403)
.antMatchers("/login").anonymous()
.anyRequest().authenticated()
.and()
//Setup a custom login page
.formLogin()
.loginPage("/login")
.usernameParameter("username")
.passwordParameter("password")
.and()
.httpBasic()
}


override fun configure(auth: AuthenticationManagerBuilder) {
//Sets up a user store in memory. Useful for debugging and development
auth
.inMemoryAuthentication()
.withUser("joe")
.password("black")
.roles("USER")
.and()
.withUser("administrator")
.password("administrator")
.roles("USER", "ADMINISTRATOR")
}

哪些类型的应用程序应该使用 CSRF 保护?

 您对在浏览器中运行的 Web 应用程序采用 CSRF 保证,您应该期望转换操作可以由加载应用程序显示内容的浏览器完成。

由于应用程序具有不同的先决条件,因此系统提供的任何实现都应该足以有效地适应不同的场景。 Spring Security 中的 CSRF 安全工具也不例外。 我们仅在接受服务器提供的资源的页面本身由同一服务器创建时才使用 CSRF 保护。 它可以是一个 Web 应用程序,其中使用的端点由不同的根节点发现。

有时您可能需要自定义 CSRF 令牌的管理。正如您现在所知,默认情况下,应用程序将 CSRF 令牌存储在服务器端的 HTTP 会话中。HTTP 会话是有状态的,会降低应用程序的多功能性。假设您需要改变应用程序管理令牌的方式,并将其存储在数据库中的某个位置,而不是 HTTP 会话中。Spring Security 提供了两种方法来执行此操作:

  • CsrfToken:描述 CSRF 令牌本身
  • CsrfTokenRepository:描述创建、存储和加载 CSRF 令牌的对象

建议

通常,您只需要CsrfToken的实例来将详细信息存储在请求的属性中。CsrfTokenRepository可用于在 Spring Security 中管理 CSRF 令牌。接口CsrfTokenRepository是与管理 CSRF 令牌的组件通信的契约。要更改应用程序管理令牌的方式,您需要实现CsrfTokenRepository接口,该接口允许您将自定义实现插入系统中。

无论如何,在使用此类代币的网站上可以发现此调整的一些问题。我们在下面列出了其中一些:

  • 只有POST方法可以验证秘密反 CSRF 令牌。
  • 当服务器不检查令牌时,它可以被排除在攻击之外。
  • 该令牌与受害者的会话无关,基本上是从应用程序的全球池中传播的,这使得攻击者可以利用他们的神秘令牌在另一个帐户上执行活动。
  • 有可能重复使用此令牌,清除所有请求中的既定来源。

注意事项

这些都是此修复程序所展示的问题的几个案例,因为攻击者将不断尝试破坏强制验证。

在可能的解决方案中,一种是不可预测的令牌,插入 HTML 表单的隐藏字段中。我们需要在应用服务器上验证令牌,以此来施加质询。重要的是,每次我们发出请求时,服务器都会提供一个新令牌。我们将此机制称为每页令牌。

我们需要确保这个令牌是唯一的,并且我们会对应用程序中的每个操作进行检查。

结论

最后,我们强调,实施多层安全措施始终很重要。有动机的攻击者总是会寻找方法来破坏现有的保护措施。我们建议始终遵循良好的安全做法,评估风险,并尽可能减少攻击面。

一个很好的初步预防措施是将浏览配置文件分开。至少,将您的专业配置文件与个人资料分开很重要。您还可以创建其他配置文件:一个仅用于研究,另一个用于在线购物等。当然,我们必须始终了解我们在设备上安装和访问的内容。CSRF 是一个古老的 Web 应用程序安全问题,但仍然会给受害者带来负面影响。

鉴于我们这一代开发新数字产品的速度很快,考虑安全性变得越来越重要。对于开发人员来说,请记住要考虑应用程序的安全要求和操作要求。

文章来源:Kotlin CSRF Protection Guide: Examples and How to Enable It

#你可能也喜欢这些API文章!