Spring Boot项目中怎么设置内容安全策略Content Security Policy

内容安全策略(CSP,Content Security Policy) 是一种用于防止跨站点脚本攻击(XSS)和数据注入攻击的安全策略。它通过指定允许加载的资源类型(如脚本、样式表、图像等)和其来源,来减少代码执行的风险。

本文将详细介绍如何在Spring Boot项目中设置CSP,并提供完整的代码示例和解析,帮助开发者保护Web应用免受常见安全漏洞的侵害。

1. 什么是Content Security Policy?

CSP是一种Web安全策略,通过告诉浏览器只允许特定来源的内容加载,可以有效减少XSS和其它代码注入的风险。它的主要工作原理是:

  • 通过HTTP头或HTML <meta>标签定义允许的资源来源;
  • 限制页面加载外部资源的权限,如脚本、样式表、图像等。

CSP可以阻止的常见安全问题包括:

  • 跨站脚本攻击(XSS):阻止恶意脚本在页面中执行;
  • 数据注入:通过限制资源加载,减少不信任来源的数据注入可能性。

2. Spring Boot 项目中设置 CSP 的作用

在Spring Boot应用中,通过配置CSP,可以对Web应用的前端资源加载进行严格的控制,避免被恶意代码注入,提升Web应用的整体安全性。

  • 防御XSS攻击:CSP能有效阻止嵌入的恶意JavaScript代码。
  • 防止外部资源加载:CSP允许你指定加载资源的来源,防止加载未经授权的外部资源。
  • 提高应用安全:配合其他Web安全措施,如HTTP Strict Transport Security (HSTS),CSP可以增强整体安全。

3. CSP的基本配置策略

CSP策略由一系列指令(directives)组成,常见的指令包括:

  • default-src:为所有类型的资源设置默认来源。
  • script-src:为JavaScript脚本指定加载来源。
  • style-src:为样式表指定来源。
  • img-src:为图片资源指定来源。
  • connect-src:为AJAX、WebSocket等网络请求指定来源。

这些指令可以在HTTP响应头中通过Content-Security-Policy设置。

4. 在Spring Boot中设置Content Security Policy

在Spring Boot项目中,我们可以通过配置SecurityConfig类来自定义安全策略,包括CSP。Spring Security提供了对CSP的支持,你可以通过HTTP头自定义CSP。

4.1 添加Spring Security依赖

首先,在项目的pom.xml中引入Spring Security依赖:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId>
</dependency>
4.2 配置Content Security Policy

接下来,在Spring Boot项目的安全配置类中(通常是SecurityConfig),通过HttpSecurity的配置来设置CSP策略。

代码示例:

import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {http// 启用CSP策略.headers().contentSecurityPolicy("default-src 'self'; script-src 'self' https://trustedscripts.com; object-src 'none'; style-src 'self' https://trustedstyles.com").and().frameOptions().sameOrigin();}
}

解释:

  • default-src 'self':允许所有资源从与页面同源的地方加载。
  • script-src 'self' https://trustedscripts.com:仅允许页面执行来自自身或trustedscripts.com的JavaScript。
  • object-src 'none':禁止加载<object><embed>等标签的内容。
  • style-src 'self' https://trustedstyles.com:仅允许加载同源的样式表和trustedstyles.com的样式表。
4.3 禁用unsafe-inlineunsafe-eval

在某些情况下,你可能会遇到不安全的inline脚本或样式执行,如直接在HTML中嵌入<script>标签或<style>标签,或者动态地在JavaScript中执行字符串代码。这种方式存在较大的安全隐患,通常在CSP中应当禁止。

通过禁止unsafe-inlineunsafe-eval可以有效地阻止这些潜在的安全问题:

http.headers().contentSecurityPolicy("default-src 'self'; script-src 'self'; style-src 'self'; object-src 'none'; img-src 'self'; frame-ancestors 'none'").and().frameOptions().sameOrigin();
  • unsafe-inline:允许页面中直接嵌入的脚本和样式执行,通常建议禁用。
  • unsafe-eval:允许使用eval()执行字符串作为JavaScript代码,建议禁用。

5. 如何调试和测试CSP配置

5.1 使用开发者工具

使用浏览器的开发者工具可以查看CSP是否正确生效。打开浏览器控制台,查看是否有CSP相关的报错提示。

5.2 调整CSP策略

当CSP策略太严格时,可能会导致一些资源加载失败。你可以通过以下方式逐步放宽限制:

  • 使用report-uri指令来收集CSP违规报告,而不直接阻止资源加载。
  • 开启调试模式,通过记录的报告分析哪些资源被阻止。

6. Content Security Policy的高级配置

对于更加复杂的应用,可以根据需要灵活配置CSP策略。例如:

  • 允许特定的media资源:
http.headers().contentSecurityPolicy("media-src 'self' https://trustedmedia.com");
  • 允许在iframe中加载指定来源的页面:
http.headers().contentSecurityPolicy("frame-ancestors 'self' https://trustedframe.com");

7. 使用Nonce处理内联样式和脚本

在许多Web应用中,内联样式和内联脚本的使用是很常见的,尤其是在早期开发阶段或者为了快速渲染页面。然而,直接在页面中嵌入内联脚本和样式带来了XSS(跨站脚本攻击)的安全风险。因此,通常在配置Content Security Policy(CSP)时,我们会禁止unsafe-inline,阻止所有内联样式和脚本。

但是,在某些场景下,内联脚本和样式是不可避免的。 这时,我们可以通过CSP的nonce(一次性令牌)机制来允许安全的内联脚本和样式执行。通过为每个请求生成一个唯一的nonce,浏览器可以识别哪些内联样式或脚本是安全的,从而避免阻止合法代码的执行。

7.1 什么是Nonce?

nonce(Number Once)是一个临时的、唯一的字符串,它被添加到每个内联样式或脚本标签中,作为该标签的“授权令牌”。在服务器端生成并附加给HTML标签,同时在CSP头中声明该nonce,浏览器会允许带有匹配nonce的内联代码执行。

通过nonce的方式,可以在不禁用unsafe-inline的情况下,继续安全地使用内联脚本和样式。

7.2 在CSP中使用Nonce

在配置CSP时,我们可以通过script-srcstyle-src指令来指定带有特定nonce的内联脚本和样式。下面是一个示例,展示如何配置nonce

http.headers().contentSecurityPolicy("default-src 'self'; script-src 'self' 'nonce-RANDOM_NONCE'; style-src 'self' 'nonce-RANDOM_NONCE';").and().frameOptions().sameOrigin();

在上面的CSP策略中,'nonce-RANDOM_NONCE'表示带有指定nonce的脚本和样式会被允许执行,而其他内联脚本将被阻止。

7.3 生成和应用Nonce

在Spring Boot中,我们可以动态地生成一个nonce并将其应用到CSP头中,同时插入到内联的脚本或样式标签中。

示例代码:

import org.springframework.security.web.header.HeaderWriter;
import org.springframework.stereotype.Component;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.UUID;@Component
public class CSPNonceHeaderWriter implements HeaderWriter {@Overridepublic void writeHeaders(HttpServletRequest request, HttpServletResponse response) {// 动态生成唯一的 nonceString nonce = UUID.randomUUID().toString();// 将 nonce 设置到 CSP 头中response.setHeader("Content-Security-Policy", "script-src 'self' 'nonce-" + nonce + "'; style-src 'self' 'nonce-" + nonce + "'");// 你也可以将 nonce 设置到请求的属性中,以便在页面中使用request.setAttribute("nonce", nonce);}
}

 在上面的代码中,我们为每个请求生成一个唯一的nonce,并将其添加到Content-Security-Policy响应头中。然后,我们可以在页面中的内联脚本和样式中使用这个nonce

7.4 在HTML页面中应用Nonce

为了使内联脚本和样式通过CSP的验证,我们需要在内联标签中应用相同的nonce

例如,在Thymeleaf模板中,假设我们已经将生成的nonce传递到页面中,可以这样使用:

<script th:attr="nonce=${nonce}">console.log('这是安全的内联脚本');
</script><style th:attr="nonce=${nonce}">body {background-color: #f0f0f0;}
</style>

在这个例子中,使用Thymeleaf模板引擎将生成的nonce插入到内联的<script><style>标签中。由于该nonce与响应头中的Content-Security-Policy中声明的nonce一致,浏览器将允许这些内联脚本和样式执行。

7.6 在Angular中应用Nonce

因为我们项目中使用的Angular,所以我们再讲一下在angular中是怎么使用Nonce的。根据Angular官方提供的CSP方案,我们选择第2种。注意需要angular16以上的版本才支持。

有了官方的方案,接下来我们就在angular中实现动态的nonce就可以了。

7.7 如何测试Nonce

在开发环境中,你可以通过以下步骤验证nonce的工作:

  1. 查看浏览器的开发者工具:打开浏览器的开发者工具,检查是否存在CSP违规报告。如果一切正常,内联脚本和样式将成功执行。
  2. 动态生成nonce:每次请求都应该生成不同的nonce,你可以通过刷新页面,检查每次响应的Content-Security-Policy头,确认nonce是否在变化。
  3. 故意注入不匹配的nonce:你可以在页面中手动注入不匹配的nonce,验证浏览器是否会阻止这些内联代码的执行。

8. 总结

在Spring Boot项目中设置CSP策略是保护Web应用的有效方法,通过指定允许加载的资源来源,可以显著降低XSS和数据注入攻击的风险。本文介绍了CSP的基本概念、在Spring Boot中如何配置CSP以及如何进行调试和优化。

合理配置CSP策略,不仅可以提升Web应用的安全性,还可以为用户提供更加安全的浏览体验。尤其是通过nonce机制可以在确保安全的同时灵活使用内联样式和脚本。在CSP中应用nonce,可以帮助开发者在保持项目安全性的同时,避免由于禁止unsafe-inline而导致的内联代码执行问题。

通过本文的内容,相信你已经能够在自己的Spring Boot项目中配置并应用CSP策略,如何通过nonce来处理内联样式和脚本的安全问题,为Web应用加上一层强大的防护!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/453748.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python爬虫之小白入门保姆级教程,带7个爬虫小案例(附源码)!

以下是一份 Python 爬虫入门保姆级教程&#xff1a; 一、准备工作 安装 Python 前往 Python 官方网站&#xff08;https://www.python.org/&#xff09;下载适合你操作系统的 Python 版本并安装。安装过程中可以勾选“Add Python to PATH”以便在命令行中方便地调用 Python。 …

初识git · 有关模型

目录 前言&#xff1a; 有关开发模型 前言&#xff1a; 其实文章更新到这里的时候&#xff0c;我们已经学习了可以满足我们日常生活中的基本需求的指令了&#xff0c;但是为什么要更新本篇文章呢&#xff1f;是因为实际生活中我们对于开发工作&#xff0c;运维工作&#xff…

ubuntu查看系统版本命令

查看系统版本指令 在 Ubuntu 操作系统中&#xff0c;您可以使用多个命令来查看系统版本。以下是一些常用的命令&#xff1a; lsb_release -a 这个命令会显示详细的 Ubuntu 版本信息&#xff0c;包括发行版名称、版本号、代号等。lsb_release -acat /etc/os-release 这个命令会显…

基于SSM的的水电管理系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏&#xff1a;…

5G工业路由器智能电网部署实录:一天内解决供电、网络

凌晨4:13,我被手机震动惊醒。变电站值班人员发来紧急消息:昨晚部署的SR800突然离线。我立即查看了STAR Device Manager平台,确认是设备A37号在3:47分失去连接。(key-iot.com/iotlist/sr800-3.html) 6:30到达变电站。检查SR800状态,发现是供电问题导致设备重启。这个老旧变电站…

pytorch训练和使用resnet

pytorch训练和使用resnet 使用 CIFAR-10数据集 训练 resnet resnet-train.py import torch import torchvision import torchvision.transforms as transforms import torch.nn as nn import torch.optim as optim# 在CIFAR-10数据集中 # 训练集&#xff1a;包含50000张图像…

电影院订票选座小程序ssm+论文源码调试讲解

第2章 开发环境与技术 电影院订票选座小程序的编码实现需要搭建一定的环境和使用相应的技术&#xff0c;接下来的内容就是对电影院订票选座小程序用到的技术和工具进行介绍。 2.1 MYSQL数据库 本课题所开发的应用程序在数据操作方面是不可预知的&#xff0c;是经常变动的&…

处理文件上传和进度条的显示(进度条随文件上传进度值变化)

成品效果图&#xff1a; 解决问题&#xff1a;上传文件过大时&#xff0c;等待时间过长&#xff0c;但是进度条却不会动&#xff0c;只会在上传完成之后才会显示上传完成 上传文件的upload.component.html <nz-modal [(nzVisible)]"isVisible" [nzTitle]"文…

python包以及异常、模块、包的综合案例(较难)

1.自定义包 python中模块是一个文件&#xff0c;而包就是一个文件夹 有这个_init_.py就是python包&#xff0c;没有就是简单的文件夹 包的作用&#xff1a;当我们的模块越来越多时&#xff0c;包可以帮助我们管理这些模块&#xff0c;包的作用就是包含多个模块&#xff0c;但包…

【命令操作】信创终端系统上timedatectl命令详解 _ 统信 _ 麒麟 _ 方德

原文链接&#xff1a;【命令操作】信创终端系统上timedatectl命令详解 | 统信 | 麒麟 | 方德 Hello&#xff0c;大家好啊&#xff01;今天给大家带来一篇关于如何在信创终端系统上使用timedatectl命令的详细介绍。timedatectl 是Linux系统中非常实用的时间管理工具&#xff0c;…

学习写作--polyGCL.md

POLYGCL: GRAPH CONTRASTIVE LEARNING VIA LEARNABLE SPECTRAL POLYNOMIAL filters 这篇工作的摘要和引言写的特别好&#xff08;不愧是ICLR spotlight&#xff09; 摘要 第一步&#xff0c;设定背景 Recently, Graph Contrastive Learning (GCL) has achieved significantl…

使用Flask实现本机的模型部署

前言 模型部署是指将大模型运行在专属的计算资源上&#xff0c;使模型在独立的运行环境中高效、可靠地运行&#xff0c;并为业务应用提供推理服务。其目标是将机器学习模型应用于实际业务中&#xff0c;使最终用户或系统能够利用模型的输出&#xff0c;从而发挥其作用。 一、设…

12 django管理系统 - 注册与登录 - 登录

为了演示方便&#xff0c;我就直接使用models里的Admin来演示&#xff0c;不再创建用户模型了。 ok&#xff0c;先做基础配置 首先是在base.html中&#xff0c;新增登录和注册的入口 <ul class"nav navbar-nav navbar-right"><li><a href"/ac…

黑马软件测试第一篇_Linux

Linux 操作系统 说明: 所有硬件设备组装完成后的第⼀一层软件, 能够使⽤用户使⽤用硬件设备的软件 即为操作系统 常见分类 桌⾯面操作系统: Windows/macOS/Linux移动端操作系统: Android(安卓)/iOS(苹果)服务器器操作系统: Linux/Windows Server嵌⼊入式操作系统: Android(底…

linux线程 | 同步与互斥 | 线程池以及知识点补充

前言&#xff1a;本节内容是linux的线程的相关知识。本篇首先会实现一个简易的线程池&#xff0c; 然后再将线程池利用单例的懒汉模式改编一下。 然后再谈一些小的知识点&#xff0c;比如自旋锁&#xff0c; 读者写者问题等等。 那么&#xff0c; 现在开始我们的学习吧。 ps:本…

吴恩达深度学习笔记(6)

正交化 为了提高算法准确率&#xff0c;我们想到的方法 收集更多的训练数据增强样本多样性使用梯度下降将算法使算法训练时间更长换一种优化算法更复杂或者更简单的神经网络利用dropout 或者L2正则化改变网络框架更换激活函数改变隐藏单元个数 为了使有监督机制的学习系统良…

ansible playbooks

文章目录 一&#xff0c;ansible剧本二&#xff0c;ansible playbooks主要特性三&#xff0c;yaml基本语法规则四&#xff0c;剧本playbooks的组成结构五&#xff0c;yaml编写1.示例2.运行playbook2.1 运行2.2 检查yaml文件的语法是否正确2.3 检查tasks任务2.3 检查生效的主机2…

maven创建父子项目

创建父类 创建子模块 添加文件夹 配置tomcat 参考 然后启动项目即可 参考 https://blog.csdn.net/gjtao1130/article/details/115000022

Linux——shell 编程基础

基本介绍 shell 变量 环境变量&#xff08;也叫全局变量&#xff09; 位置参数变量 预定义变量 运算符 条件判断 流程控制 if 单分支&多分支 case 语句 for循环 while 循环 read 读取控制台输入 函数 系统函数 basename 获取文件名 dirname 获取目录路径 自定义函数 综…

DataWhale10月动手实践——Bot应用开发task03学习笔记

一、工作流 1. 工作流的定义 工作流由多个节点组成&#xff0c;这些节点可以包括大语言模型&#xff08;LLM&#xff09;、代码模块、逻辑判断工具、插件等。每个节点需要不同的信息来执行其功能。工作流的核心含义是&#xff1a;对工作流程及其操作步骤之间的业务规则进行抽…