使用内容安全策略 (CSP) 在 Spring Boot 中防止跨站点脚本 (XSS)

介绍

使用 Web 应用程序时用户及其个人数据的安全至关重要。 尽管这一指导原则甚至在 Web 开发的早期阶段就已得到认可——不良行为者会发现应用程序中的漏洞,并可能利用您的用户。

许多“标准”攻击是众所周知的并且有记录的,并且对它们的保护并不难。 为了减轻开发人员自己实施安全实践的负担,像 Spring Boot 这样的框架已经抽象出各种安全措施,并允许您在应用程序中简单地应用安全过滤器来防止众所周知的攻击。

在这个简短的指南中,我们将了解什么是跨站点脚本 (XSS),有人如何对您自己的应用程序执行这种攻击,以及如何使用 Spring Boot 轻松阻止它。

什么是跨站脚本 (XSS)?

Cross-Site Scripting 是一种广为人知的、广泛传播的漏洞利用,其中不法分子将脚本注入 Web 应用程序。

通常,同源策略应用于 Web 应用程序,如果它们的来源不匹配,它会限制网页中的脚本访问来自源的数据。 在同源策略下——如果一个页面来自 受信任的网站 可以访问与用户交互的数据(例如 cookie),来自同一来源的其他页面也可以这样做。 这种形式的访问控制在当时似乎足以保护 Web 应用程序上数据的完整性。

跨站脚本绕过同源策略,通过将恶意脚本注入到受信任网站的页面中。 由于脚本是从受信任的网站运行的,因此它作为受信任的脚本执行。 没有明确的方法来区分恶意脚本和非恶意脚本 - 因此跨站点脚本可以执行任意代码。 这包括从插入恼人的警报到社会工程攻击、静默收集用户信息或将用户重定向到看似受信任网站一部分的网络钓鱼页面。

更多来自Google的 网站很容易受到跨站点脚本攻击,并且它在今天仍然是一种常见的攻击,尽管这种类型的攻击自 90 年代就已经为人所知。

使用内容安全策略 (CSP) 在 Spring Boot 应用程序中防止 XSS

Spring Boot 非常重视安全性,Spring 的 Security 模块实现了灵活而强大的安全实践,使开发人员可以最大限度地减少安全方面的担忧,这通常需要对 Web 中消息交换方式的原理有一个低层次的理解应用。

默认情况下,Spring Boot 实现了几个安全头:

Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Content-Type-Options: nosniff
Strict-Transport-Security: max-age=31536000 ; includeSubDomains
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block

默认包含 X-XSS-Protection! 此安全标头试图 检测 XSS 尝试并阻止它们。 不过,这不是一个防故障过程,并且浏览器有不同的检测器实现。 有些浏览器,比如 Chrome,甚至 删除了他们的 XSS Auditor. 此外,自动检测适用于 反射型 XSS 攻击,而其他类型的攻击也存在。

X-XSS-Protection 的一个更现代的替代方案是 内容安全策略 (CSP),它主要处理关于可以加载哪些资源、从哪些来源以及在哪些端点的策略。 截至 2022 年,CS​​P 是针对 XSS、Clickjacking 和其他类型攻击的最佳预防措施。 并非所有浏览器都实现 CSP,这就是默认情况下它不包含在安全标头中的原因。

请注意: 即使有 CSP,它始终是验证的最佳行动方案 任何 用户输入并确保使用您的系统进行处理是安全的,以防止代码注入。

在 Spring Boot 中——要配置自定义 Web 安全措施,您通常会扩展 WebSecurityConfigurerAdapter 类,并覆盖 configure() 方法:

@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

@Override
protected void configure(HttpSecurity http) throws Exception {
	http
	.headers()
		.contentSecurityPolicy("csp-directives");
    }
}

其中内容安全策略指令(作为 ;-separated string) 取决于您的用例和您希望信任的来源:

Content-Security Policy: directive1; directive2; directive3; ... directiveN;

例如,Web 应用程序可以列出可以从中加载脚本的受信任网站:

script-src https://trusted.com;

或者您可以跳过信任任何第三方网站:

script-src self;

同样,应用程序可以信任插件:

object-src https://trusted.com

您可以提供多种指令,包括:

  • default-src - 默认回退
  • child-src – 有效的网络工作者来源
  • frame-src – 有效来源 并且 s
  • img-src – 图像的有效来源
  • media-src – 有效来源 , 标签
  • script-src - 有效的脚本源(有助于防止 XSS)
  • style-src – 有效来源 分子
  • base-uri – 限制从 element
  • frame-ancestors – 有效的父母 , , 等元素
  • 等等

查看我们的 Git 学习实践指南,其中包含最佳实践、行业认可的标准以及随附的备忘单。 停止谷歌搜索 Git 命令,实际上 学习 它!

例如,这是一组安全的策略指令:

script-src 'strict-dynamic' 'nonce-rAnd0m123' 'unsafe-inline' http: https:;
object-src 'none';
base-uri 'none';
require-trusted-types-for 'script';
report-uri https://csp.example.com;

让我们将这些添加到我们的 Spring Boot 应用程序中:

@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

@Override
protected void configure(HttpSecurity http) throws Exception {
	http
	.headers()
		.contentSecurityPolicy("script-src 'strict-dynamic' 'nonce-rAnd0m123' 'unsafe-inline' http: https:; object-src 'none'; base-uri 'none'; require-trusted-types-for 'script'; report-uri https://csp.example.com;");
    }
}

您可以使用 CSP 评估器 评估您的 CSP 指令是否有效 安全,它会指出哪些指令很容易被利用。 这是一个允许使用 Google API 的 CSP 指令:

default-src 'self';
object-src 'none';
frame-src 'self' data:; 
script-src 'self' 'strict-dynamic' 'nonce-rAnd0m123' 'unsafe-inline' https://storage.googleapis.com; 
style-src 'self' 'unsafe-inline'; 
img-src 'self' data:; 
font-src 'self' data:;
base-uri 'self'

结论

在这个简短的指南中,我们了解了跨站点脚本 (XSS) 是什么,以及它是如何在整体层面上工作的。 然后,我们探索了一些可以使用 Spring Boot 轻松实现的 XSS 预防措施,以确保您的应用程序安全,并设置一个 内容安全策略 (CSP)。

最后,我们探索了 CSP 指令并查看了几个不同的安全策略。

时间戳记:

更多来自 堆栈滥用