元素码农
基础
UML建模
数据结构
算法
设计模式
网络
TCP/IP协议
HTTPS安全机制
WebSocket实时通信
数据库
sqlite
postgresql
clickhouse
后端
rust
go
java
php
mysql
redis
mongodb
etcd
nats
zincsearch
前端
浏览器
javascript
typescript
vue3
react
游戏
unity
unreal
C++
C#
Lua
App
android
ios
flutter
react-native
安全
Web安全
测试
软件测试
自动化测试 - Playwright
人工智能
Python
langChain
langGraph
运维
linux
docker
工具
git
svn
🌞
🌙
目录
▶
注入攻击与防御
SQL注入原理与利用
SQL注入防御策略
NoSQL注入技术分析
命令注入漏洞实战
ORM框架注入问题
注入攻击自动化检测
▶
认证与会话安全
会话固定与会话劫持
密码存储与加密策略
多因素认证机制
OAuth2.0安全实践
JWT安全攻防
认证逻辑漏洞挖掘
▶
XSS攻击与防御
XSS攻击原理与分类
存储型XSS实战案例
DOM型XSS高级利用
XSS过滤器绕过技术
CSP内容安全策略
前端框架XSS防护
▶
CSRF与点击劫持
CSRF攻击原理演示
CSRF Token防御实践
点击劫持技术剖析
SameSite Cookie策略
框架内置防护机制
跨域资源安全策略
▶
文件安全攻防
文件上传漏洞利用
安全文件类型验证
路径遍历漏洞实战
文件包含漏洞防御
Office文档攻击解析
云存储安全配置
▶
其他Web攻击技术
SSRF漏洞利用与防御
XXE漏洞攻防实战
反序列化漏洞原理
业务逻辑漏洞挖掘
HTTP请求走私攻击
Web缓存投毒攻击
发布时间:
2025-03-23 13:09
↑
☰
# CSP内容安全策略 ## CSP概述 CSP(Content Security Policy,内容安全策略)是一种额外的安全层,用于检测并防止XSS和其他代码注入攻击。通过CSP,我们可以指定浏览器只能加载指定来源的内容,从而大大降低XSS攻击的风险。 ## CSP配置方法 ### 1. HTTP头部配置 ```javascript // Express中间件配置CSP app.use((req, res, next) => { // 基本CSP配置 res.setHeader('Content-Security-Policy', "default-src 'self'; " + "script-src 'self' 'unsafe-inline' 'unsafe-eval'; " + "style-src 'self' 'unsafe-inline'; " + "img-src 'self' data: https:; " + "font-src 'self'; " + "frame-src 'none'; " + "object-src 'none';" ); next(); }); // 使用Helmet配置CSP const helmet = require('helmet'); app.use(helmet.contentSecurityPolicy({ directives: { defaultSrc: ["'self'"], scriptSrc: ["'self'", "'unsafe-inline'"], styleSrc: ["'self'", "'unsafe-inline'"], imgSrc: ["'self'", 'data:', 'https:'], fontSrc: ["'self'"], frameSrc: ["'none'"], objectSrc: ["'none'"] } })); ``` ### 2. Meta标签配置 ```html <!-- 在HTML中配置CSP --> <meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self' 'unsafe-inline'"> <!-- 仅报告模式 --> <meta http-equiv="Content-Security-Policy-Report-Only" content="default-src 'self'; report-uri /csp-violation"> ``` ## CSP指令详解 ### 1. 基本指令 ```javascript // CSP指令配置器 class CSPDirectiveBuilder { constructor() { this.directives = new Map(); } // 设置默认源 setDefaultSrc(sources) { this.directives.set('default-src', sources); return this; } // 设置脚本源 setScriptSrc(sources) { this.directives.set('script-src', sources); return this; } // 设置样式源 setStyleSrc(sources) { this.directives.set('style-src', sources); return this; } // 设置图片源 setImgSrc(sources) { this.directives.set('img-src', sources); return this; } // 生成CSP头部值 build() { const parts = []; for (let [directive, sources] of this.directives) { parts.push(`${directive} ${sources.join(' ')}`); } return parts.join('; '); } } // 使用示例 const builder = new CSPDirectiveBuilder() .setDefaultSrc(["'self'"]) .setScriptSrc(["'self'", "'unsafe-inline'", 'trusted-cdn.com']) .setStyleSrc(["'self'", "'unsafe-inline'"]) .setImgSrc(["'self'", 'data:', 'https:']); const cspHeader = builder.build(); ``` ### 2. 高级指令 ```javascript // CSP高级配置 class AdvancedCSPConfig { constructor() { this.config = { // 基本源限制 'default-src': ["'self'"], // 脚本控制 'script-src': [ "'self'", "'strict-dynamic'", "'nonce-${this.generateNonce()}'" ], // 样式控制 'style-src': ["'self'"], // 媒体控制 'img-src': ["'self'", 'data:', 'https:'], 'media-src': ["'self'"], 'font-src': ["'self'"], // 框架控制 'frame-src': ["'none'"], 'child-src': ["'none'"], 'frame-ancestors': ["'none'"], // 其他资源控制 'object-src': ["'none'"], 'manifest-src': ["'self'"], // 连接控制 'connect-src': ["'self'"], // 表单控制 'form-action': ["'self'"], // 插件控制 'plugin-types': ['application/pdf'], // 沙箱控制 'sandbox': [ 'allow-scripts', 'allow-same-origin', 'allow-forms' ], // 升级不安全请求 'upgrade-insecure-requests': '', // 基础URI限制 'base-uri': ["'self'"], // 引用策略 'referrer': ['strict-origin-when-cross-origin'], // 报告配置 'report-uri': ['/csp-violation'], 'report-to': ['csp-endpoint'] }; } generateNonce() { return crypto.randomBytes(16).toString('base64'); } getHeader() { const parts = []; for (let [directive, values] of Object.entries(this.config)) { if (Array.isArray(values)) { parts.push(`${directive} ${values.join(' ')}`); } else if (values) { parts.push(directive); } } return parts.join('; '); } } ``` ## 违规报告处理 ### 1. 报告接收器 ```javascript // CSP违规报告处理器 class CSPViolationHandler { constructor() { this.violations = new Map(); } // 处理CSP违规报告 handleViolation(req, res) { const report = req.body; // 记录违规信息 const violation = { timestamp: new Date(), blockedUri: report['blocked-uri'], violatedDirective: report['violated-directive'], documentUri: report['document-uri'], originalPolicy: report['original-policy'], browserInfo: req.headers['user-agent'] }; // 存储违规记录 this.storeViolation(violation); // 发送告警 if (this.shouldAlert(violation)) { this.sendAlert(violation); } res.status(204).end(); } // 存储违规记录 storeViolation(violation) { const key = `${violation.documentUri}:${violation.violatedDirective}`; if (!this.violations.has(key)) { this.violations.set(key, []); } this.violations.get(key).push(violation); } // 判断是否需要告警 shouldAlert(violation) { const key = `${violation.documentUri}:${violation.violatedDirective}`; const violations = this.violations.get(key) || []; // 检查违规频率 const recentViolations = violations.filter(v => (new Date() - v.timestamp) < 3600000 // 1小时内 ); return recentViolations.length >= 10; } // 发送告警 sendAlert(violation) { // 实现告警逻辑 console.error('CSP Violation Alert:', violation); } } ``` ### 2. 报告分析 ```javascript // CSP违规分析器 class CSPViolationAnalyzer { constructor(violations) { this.violations = violations; } // 分析违规模式 analyzePatterns() { const patterns = new Map(); for (let violation of this.violations) { const key = `${violation.violatedDirective}:${violation.blockedUri}`; if (!patterns.has(key)) { patterns.set(key, { count: 0, examples: [] }); } const pattern = patterns.get(key); pattern.count++; if (pattern.examples.length < 5) { pattern.examples.push({ timestamp: violation.timestamp, documentUri: violation.documentUri }); } } return patterns; } // 生成建议 generateRecommendations() { const patterns = this.analyzePatterns(); const recommendations = []; for (let [key, data] of patterns) { const [directive, uri] = key.split(':'); if (data.count > 100) { recommendations.push({ directive, uri, suggestion: this.getSuggestion(directive, uri), priority: 'high', impact: data.count }); } } return recommendations; } // 获取具体建议 getSuggestion(directive, uri) { // 根据不同情况提供建议 if (uri.startsWith('https://') && this.isCommonCDN(uri)) { return `Consider adding '${uri}' to ${directive}`; } if (uri === 'eval') { return `Consider refactoring code to avoid using eval()`; } return `Review the necessity of loading content from '${uri}'`; } // 检查是否是常见CDN isCommonCDN(uri) { const commonCDNs = [ 'cdn.jsdelivr.net', 'unpkg.com', 'cdnjs.cloudflare.com' ]; return commonCDNs.some(cdn => uri.includes(cdn)); } } ``` ## 最佳实践 ### 1. 基本原则 1. 最小权限原则 - 只允许必要的资源加载 - 禁用不需要的功能 - 使用nonce或hash验证内联脚本 2. 分层防御 - 结合其他安全头部 - 实施报告和监控 - 定期审查和更新策略 ### 2. 配置建议 ```javascript // CSP配置生成器 class CSPConfigGenerator { constructor(environment) { this.environment = environment; this.config = this.getBaseConfig(); } // 获取基础配置 getBaseConfig() { return { 'default-src': ["'self'"], 'script-src': ["'self'"], 'style-src': ["'self'"], 'img-src': ["'self'"], 'connect-src': ["'self'"], 'font-src': ["'self'"], 'object-src': ["'none'"], 'media-src': ["'self'"], 'frame-src': ["'none'"] }; } // 添加开发环境配置 addDevelopmentConfig() { if (this.environment === 'development') { this.config['script-src'].push("'unsafe-eval'"); this.config['style-src'].push("'unsafe-inline'"); } return this; } // 添加CDN配置 addCDNConfig(cdnUrls) { for (let url of cdnUrls) { this.config['script-src'].push(url); this.config['style-src'].push(url); } return this; } // 添加API配置 addAPIConfig(apiUrls) { this.config['connect-src'].push(...apiUrls); return this; } // 添加报告配置 addReportingConfig(reportUrl) { this.config['report-uri'] = [reportUrl]; return this; } // 生成最终配置 generate() { const parts = []; for (let [directive, sources] of Object.entries(this.config)) { if (Array.isArray(sources)) { parts.push(`${directive} ${[...new Set(sources)].join(' ')}`); } else { parts.push(`${directive} ${sources}`); } } return parts.join('; '); } } // 使用示例 const generator = new CSPConfigGenerator('production') .addCDNConfig([ 'https://cdn.jsdelivr.net', 'https://cdnjs.cloudflare.com' ]) .addAPIConfig([ 'https://api.example.com'