道路千万条,安全第一条!要对付XSS等攻击你有什么手段?你知道什么是CSP吗?

前言

道路千万条,安全第一条!在开发的世界里安全也是绕不开的话题,关于前端的安全问题有XSS、CSRF等常见的。但是不管怎么防都有可能被攻击者突防,有没有更安全的手段呢?

什么是CSP

内容安全策略 (Content Security Policy, CSP) 是一个计算机安全标准,通过一个特殊的 HTTP 响应头 (Content-Security-Policy) 来实现。

它的核心目的是帮助检测和缓解特定类型的网络攻击,如跨站脚本 (XSS) 和数据注入攻击。

简单来说,CSP 就像一份白名单。你作为网站管理员,可以通过 CSP 告诉浏览器:"我的网站只允许从以下这些可信的来源加载脚本、图片、样式等资源,其他的统统拒绝!"

为什么需要CSP

在没有 CSP(Content-Security-Policy)的时代,浏览器会无条件地加载和执行它从任何地方收到的内容。这导致了严重的安全问题,尤其是 XSS 攻击。

XSS 攻击示例: 假设一个博客网站允许用户发表评论,但没有对评论内容进行严格过滤。攻击者可以提交这样一条评论:

xml 复制代码
<script>
  alert('你被攻击了!');
  // 或者更恶意的:窃取用户的Cookie、重定向到钓鱼网站等
</script>

当其他用户浏览这条评论时,浏览器会毫不犹豫地执行这段恶意脚本,因为它无法区分这是网站本身的合法脚本还是攻击者注入的恶意脚本。

CSP 如何解决这个问题? 管理员可以设置一个 CSP 策略:

Content-Security-Policy: script-src 'self'

这个策略的意思是:"只允许执行来自本网站自身域名的脚本。" 当浏览器收到这个策略后,再遇到那个恶意

CSP如何工作?

  1. 服务器发送策略:网站在 HTTP 响应头中包含 Content-Security-Policy 头,其中包含定义好的策略指令。
  2. 浏览器接收并解析策略:浏览器收到响应后,会解析并记住这些规则。
  3. 浏览器强制执行策略:在加载和执行页面中的任何资源(脚本、样式、图片、字体等)时,浏览器会逐一检查这些资源是否符合 CSP 策略。任何违反策略的行为都会被立即阻止,并且可以在控制台中看到详细的报告。

CSP常见指令

CSP 策略由一系列指令组成,每个指令控制一种特定类型的资源:

指令 含义 示例
default-src 其他资源类型的默认策略(是备用选项) default-src 'self'
script-src 控制 JavaScript 脚本的来源 script-src 'self' apis.google.com
style-src 控制 CSS 样式表的来源 style-src 'self' 'unsafe-inline'
img-src 控制图片的来源 img-src 'self' cdn.example.com
font-src 控制网页字体的来源 font-src fonts.gstatic.com
connect-src 控制 XMLHttpRequest, WebSocket 等连接的目标 connect-src 'self' api.example.com
frame-src 控制 iframe 的嵌入来源(已被 child-src 等取代,但仍常用) frame-src 'none' (禁止所有iframe)
report-uri (或 report-to) 告诉浏览器如果策略被违反,将错误报告发送到哪个URL report-uri /csp-violation-report-endpoint

常用的来源关键字

  • 'self':只允许来自当前域名(相同协议和端口)的资源。
  • 'none':禁止任何来源。
  • 'unsafe-inline':允许内联的
  • 'unsafe-eval':允许使用 eval() 等动态代码执行函数(会降低安全性)。
  • https::只允许通过 HTTPS 加载资源。

CSP 的优点

  • 有效减缓 XSS 攻击:这是最主要的好处,使得即使网站存在注入漏洞,攻击脚本也难以执行。
  • 控制资源加载:防止第三方资源被恶意替换或篡改(例如,确保 jQuery 库只从你指定的CDN加载,而不是攻击者的服务器)。
  • 上报违规行为:通过 report-uri 指令,你可以收集到关于潜在攻击的实时报告,有助于发现和修复安全漏洞。

怎么样使用CSP

使用 Helmet 设置内容安全策略 (CSP) 是保护 Web 应用程序的关键步骤。以下是设置 Helmet 内容安全策略的步骤:

使用 npm 或 yarn 安装 Helmet 包,它们是 JavaScript 和 Node.js 开发人员常用的两个包管理器。它们便于管理项目的依赖项,依赖项是项目正常运行所需的任何代码或库。

复制代码
npm install helmet

将 helmet 包导入到你的 Node.js 应用程序中:

ini 复制代码
const helmet = require('helmet');

使用 helmet.contentSecurityPolicy() 中间件函数来设置 CSP 策略:

less 复制代码
app.use(helmet.contentSecurityPolicy({

  directives: {

    defaultSrc: ["'self'"],

    scriptSrc: ["'self'", "'unsafe-inline'", 'example.com'],

    styleSrc: ["'self'", "'unsafe-inline'"],

    imgSrc: ["'self'", 'example.com'],

    connectSrc: ["'self'"],

    fontSrc: ["'self'"],

    objectSrc: ["'none'"],

    mediaSrc: ["'self'"]

  }

}));

在下面的示例中,我们将 default-src 指令设置为 'self',并在 HTTP 头中设置。你也可以在 HTTP 头中设置其他指令,但请确保它们与 helmet.contentSecurityPolicy() 中间件的指令对象匹配。

javascript 复制代码
app.use((req, res, next) => {

  res.setHeader('Content-Security-Policy', "default-src 'self';");

  next();

});

实践建议

直接部署一个严格的 CSP 可能会破坏现有网站(因为很多旧代码依赖内联脚本)。推荐采用以下步骤:

  1. 仅报告模式:开始时,不要强制执行策略,只让浏览器报告违规行为。使用 Content-Security-Policy-Report-Only 头 instead of Content-Security-Policy。
css 复制代码
Content-Security-Policy-Report-Only: default-src 'self'; report-uri /csp-report
  1. 分析报告:查看浏览器发送的违规报告,了解你的网站需要哪些资源来源,并调整你的策略。
  2. 逐步收紧策略:根据报告分析结果,逐步添加更具体的指令(如 script-src, img-src),并移除宽松的关键字(如 'unsafe-inline')。
  3. 切换到强制执行模式:当你确认策略不会阻断网站的正常功能后,将响应头改为 Content-Security-Policy,开始正式强制执行。

内容安全策略 (CSP) 是一个极其强大的安全层,它通过创建资源加载的白名单,极大地增加了攻击者实施 XSS 和数据注入攻击的难度。对于任何重视安全的现代网站来说,部署 CSP 都应该是一项必不可少的安全措施。

相关推荐
你挚爱的强哥2 分钟前
SCSS上传图片占位区域样式
前端·css·scss
奶球不是球2 分钟前
css新特性
前端·css
Nicholas684 分钟前
flutter滚动视图之Viewport、RenderViewport源码解析(六)
前端
无羡仙14 分钟前
React 状态更新:如何避免为嵌套数据写一长串 ...?
前端·react.js
Cisyam40 分钟前
使用Bright Data API轻松构建LinkedIn职位数据采集系统
后端
float_六七41 分钟前
Spring Boot 3为何强制要求Java 17?
java·spring boot·后端
TimelessHaze41 分钟前
🔥 一文掌握 JavaScript 数组方法(2025 全面指南):分类解析 × 业务场景 × 易错点
前端·javascript·trae
bobz9651 小时前
ovs arp
后端
_風箏1 小时前
SpringBoot【集成ElasticSearch 01】2种方式的高级客户端 RestHighLevelClient 使用(依赖+配置+客户端API测试源码
后端
用户21411832636021 小时前
dify案例分享-零基础上手 Dify TTS 插件!从开发到部署免费文本转语音,测试 + 打包教程全有
后端