前端小食堂 | Day17 - 前端安全の金钟罩

发布于:2025-03-19 ⋅ 阅读:(19) ⋅ 点赞:(0)

🛡️ 今日盾牌:XSS/CSRF 攻防全解析

1. XSS 防御の三重结界
// 🚫 危险操作:直接渲染未过滤内容  
document.getElementById('content').innerHTML = userInput;  

// ✅ 安全姿势一:文本转义  
const escapeHTML = (str) => {  
  const map = { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' };  
  return str.replace(/[&<>"']/g, m => map[m]);  
};  

// ✅ 安全姿势二:使用安全库  
import DOMPurify from 'dompurify';  
const safeHTML = DOMPurify.sanitize(userInput);  

// ✅ 安全姿势三:CSP 内容安全策略  
// HTTP 响应头设置:  
Content-Security-Policy: default-src 'self'; script-src 'unsafe-inline' 'nonce-随机字符串'  

🔔 攻击类型识别

  • 存储型 XSS:恶意脚本存入数据库(如评论功能)
  • 反射型 XSS:通过 URL 参数注入(如搜索框回显)
  • DOM 型 XSS:前端脚本直接操作 DOM 引发

2. CSRF 防御の四象阵法
// 🚫 危险操作:无防护的敏感请求  
axios.post('/transfer', { to: 'hacker', amount: 1000 });  

// ✅ 防御阵法一:验证 Token  
// 服务端生成并返回:  
res.cookie('csrf-token', randomToken, { httpOnly: true });  

// 前端请求携带:  
axios.post('/api', data, {  
  headers: { 'X-CSRF-Token': getCookie('csrf-token') }  
});  

// ✅ 防御阵法二:SameSite Cookie  
Set-Cookie: sessionId=xxx; SameSite=Lax; Secure  

// ✅ 防御阵法三:双重验证(验证码)  
if (isSensitiveAction) await verifyCaptcha();  

// ✅ 防御阵法四:Origin 验证  
const origin = req.headers.origin || req.headers.referer;  
if (!validOrigins.includes(origin)) return 403;  

❄️ 冷知识:现代浏览器安全机制

// 🛡️ Trusted Types API(禁止危险DOM操作)  
// 服务端响应头:  
Content-Security-Policy: trusted-types dompurify;  

// 前端代码:  
if (window.trustedTypes) {  
  const policy = trustedTypes.createPolicy('escapePolicy', {  
    createHTML: input => DOMPurify.sanitize(input)  
  });  
  element.innerHTML = policy.createHTML(untrustedInput);  
}  

// 🛡️ 加密敏感数据  
const encrypted = await crypto.subtle.encrypt(  
  { name: 'AES-GCM' },  
  secretKey,  
  new TextEncoder().encode('机密数据')  
);  

🌟 实验室安全工坊

实现 CSRF 防御中间件

// 服务端中间件(Node.js)  
const csrfProtection = (req, res, next) => {  
  const { method } = req;  
  if (['POST', 'PUT', 'DELETE'].includes(method)) {  
    const csrfToken = req.headers['x-csrf-token'];  
    const cookieToken = req.cookies['csrf-token'];  
    if (!csrfToken || csrfToken !== cookieToken) {  
      return res.status(403).json({ error: 'CSRF Token 无效' });  
    }  
  }  
  next();  
};  

// 前端请求封装  
const safeRequest = (url, data) => {  
  const token = document.cookie.match(/csrf-token=([^;]+)/)?.[1];  
  return fetch(url, {  
    method: 'POST',  
    headers: {  
      'Content-Type': 'application/json',  
      'X-CSRF-Token': token  
    },  
    body: JSON.stringify(data)  
  });  
};  

明日秘境:《身份认证の八卦阵——JWT/OAuth2 深度攻防》 🔐
(留言告诉我你经历过的安全攻防事件,本安全官为你定制防御方案!🕵️♂️)


🛎️ 本日避坑指南

  1. XSS 常见漏洞点
- 🚨 使用 `innerHTML`/`v-html` 渲染未过滤内容  
- 🚨 JSONP 回调函数未过滤参数  
- 🚨 第三方富文本编辑器未配置白名单  
- 🚨 错误的 Content-Type(如 `text/html` 响应 JSON 数据)  
  1. CSRF 错误配置
- 🚨 使用 GET 请求修改数据  
- 🚨 Cookie 未设置 SameSite 属性  
- 🚨 未校验 Referer 头部  
- 🚨 敏感操作无需二次验证  
  1. 安全头配置清单
# Nginx 安全头配置  
add_header X-Frame-Options "DENY";  
add_header X-Content-Type-Options "nosniff";  
add_header X-XSS-Protection "1; mode=block";  
add_header Content-Security-Policy "default-src 'self'";  
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";  
  1. 第三方依赖安全
# 定期检查依赖漏洞  
npm audit  
# 使用安全版本  
npx npm-force-resolutions  

🔮 安全工具速递

工具 用途
DOMPurify HTML 消毒
helmet Express 安全头中间件
Snyk 依赖漏洞扫描
ZAP Web 应用渗透测试工具
CSP Evaluator CSP 策略检测工具