当前位置: 首页 > news >正文

CSP 配置指南:SpringBoot/Express 实操 + 多域名适配,防 XSS 攻击超简单

🛡️ 普通网站必看!CSP 配置指南:SpringBoot/Express 实操 + 多域名适配,防 XSS 攻击超简单

做普通网站开发时,你是不是总担心这些问题?—— 用户遭遇 XSS 攻击导致信息泄露,页面被注入恶意广告脚本,或者非法 CDN 拖慢加载速度?其实一套合理的CSP(内容安全策略) 就能解决!今天从原理到实战,手把手教你给普通网站配 CSP,还附 SpringBoot、Node.js Express 的完整代码,多域名 + 通配符场景直接抄作业~

一、先搞懂:CSP 到底是啥?普通网站为啥需要它?

CSP(Content Security Policy)简单说就是给浏览器画 “资源白名单” —— 通过规则指定哪些域名的脚本、图片、样式能加载,哪些不能,本质是限制 “不可信资源” 的执行。

 📝 Powered by Moshow 郑锴 | 更多技术干货:https://zhengkai.blog.csdn.net/

对普通网站来说,它的作用太关键了:

  1. 🚫 防御 XSS 攻击:阻断攻击者注入的恶意 JS 脚本,保护用户账号、表单数据等信息
  2. 🚩 拦截恶意资源:禁止加载非法广告、钓鱼链接等资源,避免网站被 “污染”
  3. ⚡ 优化资源加载:只允许可信 CDN 和自有域名加载资源,减少冗余请求,提升页面速度

二、CSP 核心指令:普通网站常用这 6 个,记熟够用

CSP 用 “指令 + 值” 定义规则,普通网站开发高频用到的就这几个,关键信息已加粗:

指令作用普通网站常用值示例
default-src所有资源的 “默认规则”(兜底)'self'(自身域名)、通用 HTTPS 域名
script-src限制 JS 脚本来源(防 XSS 核心)自身域名、可信 CDN(如 jsdelivr)、子域名
img-src限制图片来源自身域名、图片 CDN、data:(base64 图)
style-src限制 CSS 样式来源自身域名、样式 CDN(如 bootcdn)
font-src限制字体文件来源自身域名、字体 CDN
frame-ancestors限制页面被 iframe 嵌套(防点击劫持)'self'、可信合作域名(如公司其他网站)

三、框架实操:SpringBoot/Express 配置 CSP(多域名 + 通配符)

这部分是重点!直接给可运行代码,只需替换成你的网站域名和常用 CDN,支持多域名(逗号分隔)和通配符(*.xxx.com),适配普通网站的资源加载场景。

🔧 场景前提

假设你的网站需要加载这些资源:

  • 自有域名:your-site.com(主域名)、*.your-site.com(子域名,如blog.your-site.com、cdn.your-site.com)
  • 可信 CDN:https://cdn.jsdelivr.net(通用 JS/CSS)、https://cdn.bootcdn.net(前端库)、https://img.abc.com(图片专用 CDN)
1. SpringBoot 版本配置(2 种通用方式)

SpringBoot 推荐用拦截器(简单通用)或Spring Security(适合有权限控制的网站,如后台管理系统),两种方式都能实现 CSP。

方式 1:拦截器配置(无权限依赖,直接用)
// 1. 新建CSP拦截器:定义规则并添加响应头
@Component
public class CspInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {// 🌟 CSP核心规则:多域名+通配符适配普通网站String cspPolicy = "default-src 'self' https://cdn.jsdelivr.net; " +"script-src 'self' https://cdn.jsdelivr.net https://cdn.bootcdn.net *.your-site.com; " + // 允许3个可信来源的JS"img-src 'self' https://img.abc.com data: *.your-site.com; " + // 支持base64图片和图片CDN"style-src 'self' https://cdn.jsdelivr.net; " + // 样式仅允许自身和通用CDN"font-src 'self' https://cdn.jsdelivr.net; " + // 字体来源限制"frame-ancestors 'self' https://partner.your-site.com;"; // 允许合作网站嵌套自身页面// 强制模式:违反规则的资源会被阻断(上线用)response.setHeader("Content-Security-Policy", cspPolicy);// 测试模式:只上报违规日志,不阻断资源(调试用,需加report-uri)// response.setHeader("Content-Security-Policy-Report-Only", cspPolicy + " report-uri /api/csp/log;");return true;}
}// 2. 注册拦截器:指定生效的网站路径
@Configuration
public class WebConfig implements WebMvcConfigurer {@Autowiredprivate CspInterceptor cspInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {// 对网站所有页面生效(可根据需求调整路径,如只给前台加:/front/**)registry.addInterceptor(cspInterceptor).addPathPatterns("/**").excludePathPatterns("/api/csp/log"); // 排除CSP日志接口,避免拦截自身}
}
方式 2:Spring Security 配置(适合带登录的网站)

如果网站用了 Spring Security 做登录验证,可直接集成 CSP,不用额外写拦截器:

@Configuration
@EnableWebSecurity
public class SecurityConfig {@Beanpublic SecurityFilterChain filterChain(HttpSecurity http) throws Exception {http.authorizeHttpRequests(auth -> auth.anyRequest().authenticated() // 示例:所有请求需登录(根据你的网站权限调整)).headers(headers -> headers// 启用CSP并配置规则.contentSecurityPolicy(csp -> csp.policyDirectives("default-src 'self' https://cdn.jsdelivr.net; " +"script-src 'self' https://cdn.jsdelivr.net *.your-site.com; " +"img-src 'self' https://img.abc.com data:; " +"frame-ancestors 'self';")).frameOptions(frame -> frame.sameOrigin()) // 配合防点击劫持);return http.build();}
}
2. Node.js Express 版本配置(用 helmet 中间件,超简单)

Express 推荐用helmet中间件(专门处理安全相关的响应头,包括 CSP),先装依赖,再写配置,3 步搞定。

步骤 1:安装 helmet 依赖
# npm或yarn都可以
npm install helmet --save
# 或
yarn add helmet
步骤 2:在入口文件(如 app.js)配置 CSP
const express = require('express');
const helmet = require('helmet');
const app = express();// 🌟 配置CSP:多域名+通配符适配普通网站
app.use(helmet.contentSecurityPolicy({directives: {defaultSrc: ["'self'", "https://cdn.jsdelivr.net"], // 默认只允许自身和通用CDNscriptSrc: ["'self'", "https://cdn.jsdelivr.net", "https://cdn.bootcdn.net", "*.your-site.com"], // JS允许3个可信来源imgSrc: ["'self'", "https://img.abc.com", "data:", "*.your-site.com"], // 图片支持CDN、base64、子域名styleSrc: ["'self'", "https://cdn.jsdelivr.net"], // 样式来源限制fontSrc: ["'self'", "https://cdn.jsdelivr.net"], // 字体仅允许可信来源frameAncestors: ["'self'"], // 禁止陌生网站嵌套自身页面(防点击劫持)// 测试阶段加:上报违规日志到接口(上线可删除或保留)// reportUri: "/api/csp/log"}
}));// 普通网站路由示例(如首页、文章页)
app.get('/', (req, res) => {res.send('普通网站首页(CSP已生效)');
});
app.get('/article/:id', (req, res) => {res.send(`文章${req.params.id}(CSP已生效)`);
});// 启动服务
app.listen(3000, () => {console.log('Express服务启动:http://localhost:3000,CSP配置已生效');
});

四、普通网站避坑指南:这 4 个错误千万别犯!

  1. ❌ 通配符 “乱用” 导致不安全
  • *.your-site.com只匹配子域名(如blog.your-site.com),不匹配主域名(your-site.com),需单独加主域名:your-site.com *.your-site.com
  • script-src别用*(会允许任何网站的 JS,等于没开 CSP),必须指定具体域名;frame-ancestors不支持*,只能写明确域名。
  1. ✅ 别漏了data:/blob:资源如果网站有用 base64 图片(如<img src="data:image/png;base64,...">)或 Blob 视频,必须在img-src/media-src里加data:/blob:,否则资源会被阻断,页面出现 “裂图”“无法播放”。

  2. ❌ 保留unsafe-inline导致 XSS 防护失效unsafe-inline允许加载内联脚本(如<script>alert(1)</script>)或内联样式(如<div style="...">),会直接抵消 CSP 的 XSS 防御效果。除非是老项目兼容(实在没办法),否则坚决删除unsafe-inline

  3. ✅ 测试阶段用 “Report-Only” 模式上线前先把Content-Security-Policy换成Content-Security-Policy-Report-Only,这样违规资源不会被阻断,但会把问题上报到reportUri接口,能快速定位漏加的域名,避免影响用户。

五、测试 CSP 是否生效:2 个简单方法(普通网站通用)

  1. 浏览器控制台直接查打开网站页面,按 F12 进入 “控制台”(Console):
  • 如果 CSP 配置成功:没有 “Refused to load the script/style/image...” 的红色错误
  • 如果配置有问题:会提示 “被 CSP 阻止”,并显示 “违反的指令”(如script-src漏加域名),按提示补充即可。
  1. 用 “日志接口” 收集问题在测试模式下配置reportUri: "/api/csp/log",然后写一个简单的接口接收日志(如 SpringBoot 的@PostMapping("/api/csp/log")),能收集所有用户端的 CSP 违规情况,适合多页面的大型网站。

六、总结:普通网站 CSP 配置模板(直接抄)

不管是 SpringBoot 还是 Express,普通网站的 CSP 核心规则都可以参考这个模板,只需替换your-site.com为你的实际域名、https://img.abc.com为你的图片 CDN:

default-src 'self' https://cdn.jsdelivr.net;
script-src 'self' https://cdn.jsdelivr.net https://cdn.bootcdn.net your-site.com *.your-site.com;
img-src 'self' https://img.abc.com data: your-site.com *.your-site.com;
style-src 'self' https://cdn.jsdelivr.net;
font-src 'self' https://cdn.jsdelivr.net;
frame-ancestors 'self';

最后想问大家:你在普通网站开发中,遇到过 XSS 攻击或恶意资源注入吗?当时是怎么解决的?评论区聊聊~

 📝 Powered by Moshow 郑锴 | 更多技术干货:https://zhengkai.blog.csdn.net/

http://www.dtcms.com/a/491545.html

相关文章:

  • 不同形态牙刮匙的适应症与使用技巧
  • Linux中处理CPU离线时清理CPU缓存page_alloc_init函数的实现
  • 单片机开发工具篇:(一)32单片机开发需要的软件和硬件
  • 旅游网站建设网足球比分网站怎么建设
  • 甘肃省建设工程安全质量监督管理局网站官网北京通州做网站
  • 数字隔离器,如何隔绝高、低压回路间的电气隐患?
  • 搜索引擎:Elasticsearch聚合,多维分析怎样实现?
  • 【0441】bgwriter 和 walwriter 都刷脏缓冲区 block到 disk file,两者有何差异?
  • 《算法与数据结构》第七章[算法4]:最短路径
  • 做网站字号多大网络营销推广方案pdf
  • 网站开发需求分析内容淄博网站制作设计高端
  • DOM CDATA
  • 动态规划----过河卒
  • 2025-10-15 ZROJ25普及联考day12 赛后总结
  • 工控人如何做自己的网站网页版微信文件传输助手
  • 南京网站建设网站高端网站建设 案例
  • Qt程序高分辨界面显示不正常解决办法
  • 如何下载Windows 11安装文件
  • Java 大视界 -- 基于 Java 的大数据隐私计算在医疗影像数据共享中的实践探索
  • 版本管理:Git Large File,二进制文件追踪?
  • 网站开发课程报告心得中国十大装修公司品牌排行榜
  • 广告设计培训机构哪家好南京谷歌seo
  • 企业活动网站创意案例铜陵市建设局网站
  • 计算机操作系统——文件系统的全局结构
  • 万万州州微微网站网站建建设设网页设计实训报告主要内容
  • pwn.college之Cryptography模块
  • wordpress 点评类网站找人做网站注意什么
  • 桥接模式详解
  • 【入门级-算法-3、基础算法:二分法】
  • 配置串口与应用