XSS 与 CSRF 安全
XSS(跨站脚本):攻击者把恶意脚本注入页面,在受害者浏览器里执行。三类:存储型(写进数据库,如评论框)、反射型(URL 参数拼到 HTML 里)、DOM 型(纯前端 JS 拼接,如 innerHTML 渲染用户输入)。防御核心是“不信任输入”:输出转义(< 换成 <)、CSP(Content-Security-Policy 限制脚本来源)、httpOnly Cookie 让 JS 拿不到、避免 innerHTML 渲染 unsanitized 数据。
CSRF(跨站请求伪造):借受害者的登录态,引诱其访问恶意页面,以受害者身份发请求(如转账)。防御:SameSite Cookie(默认 Lax 已挡大部分)、Token(每次请求带服务端发的随机 token,攻击者拿不到)、关键操作二次确认(验证码 / 密码)。
- XSS 是“执行恶意脚本”:转义输出 + CSP + httpOnly + 别用 innerHTML
- CSRF 是“借用登录态”:SameSite Cookie + Token + 关键操作二次确认
- XSS 防注入、CSRF 防借用,两类攻击的防御手段不能互换
HTML
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <!-- CSP:只允许本源与指定 CDN 的脚本,内联脚本不执行 --> <meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self' https://cdn.example.com"> <style> .out { border: 1px solid #f0c33c; padding: 8px; } </style> </head> <body> <div class="out" id="out"></div> <script> const userInput = '<img src=x onerror="alert(1)">'; // 模拟恶意输入 // 错误:直接 innerHTML → XSS 执行 // document.getElementById('out').innerHTML = userInput; // 正确 1:转义后插入 function esc(s) { return s.replace(/&/g, '&').replace(/</g, '<') .replace(/>/g, '>').replace(/"/g, '"'); } document.getElementById('out').textContent = '转义后: ' + esc(userInput); // 正确 2:用 textContent 永远不解析 HTML // 正确 3:DOMPurify 等库做富文本消毒 // CSRF 防御示例:请求带上服务端下发的 token fetch('/api/transfer', { method: 'POST', headers: { 'X-CSRF-Token': document.cookie.match(/csrf=([^;]+)/)[1] }, credentials: 'same-origin', body: JSON.stringify({ to: 'B', amount: 100 }), }); </script> </body> </html>
本节要点XSS 防注入(转义 + CSP + httpOnly),CSRF 防借用(SameSite + Token + 二次确认);两者 mechanisms 不同,防御方案也不同。




