前端安全XSS、CSRF攻击与防御大家好我是欧阳瑞Rich Own。今天想和大家聊聊前端安全这个重要话题。作为一个全栈开发者我深知前端安全的重要性。一个小小的漏洞可能会导致用户数据泄露、账户被盗甚至整个系统被攻击。为什么前端安全很重要前端是用户与应用交互的第一道防线。随着Web应用越来越复杂前端安全问题也越来越突出。根据OWASP Top 10注入攻击包括XSS和身份认证失效是最常见的安全风险。XSS攻击详解什么是XSSXSSCross-Site Scripting跨站脚本攻击是一种允许攻击者在网页中注入恶意脚本的攻击方式。XSS的类型类型描述示例场景存储型XSS恶意脚本被存储在服务器论坛帖子、评论区反射型XSS恶意脚本通过URL参数传递搜索页面、URL参数DOM型XSS恶意脚本通过DOM操作执行客户端JavaScript存储型XSS示例// 攻击者在评论区输入 scriptalert(XSS)/script // 如果后端没有过滤这条评论会被存储到数据库 // 其他用户访问时脚本会被执行反射型XSS示例// URL: http://example.com/search?queryscriptalert(XSS)/script // 如果前端直接使用URL参数 const query new URLSearchParams(window.location.search).get(query); document.getElementById(results).innerHTML 搜索结果: ${query}; // 脚本会被执行DOM型XSS示例// 前端代码 const userInput localStorage.getItem(theme); document.body.innerHTML div class${userInput}Content/div; // 如果用户输入: darkscriptalert(XSS)/scriptdiv classlight // 脚本会被执行XSS防御策略1. 输出编码// 使用textContent而不是innerHTML const userInput scriptalert(XSS)/script; document.getElementById(output).textContent userInput; // 使用DOMPurify清理HTML import DOMPurify from dompurify; const cleanHTML DOMPurify.sanitize(userInput); document.getElementById(output).innerHTML cleanHTML;2. 输入验证// 验证邮箱格式 function validateEmail(email) { const re /^[^\s][^\s]\.[^\s]$/; return re.test(email); } // 验证URL function validateURL(url) { try { const urlObj new URL(url); return urlObj.protocol https:; } catch { return false; } }3. 使用CSP内容安全策略!-- 在HTML头部设置CSP -- meta http-equivContent-Security-Policy content default-src self; script-src self strict-dynamic; style-src self unsafe-inline; img-src self data:; 4. HttpOnly和Secure Cookie// 设置HttpOnly和Secure属性 document.cookie sessionabc123; HttpOnly; Secure; SameSiteStrict;CSRF攻击详解什么是CSRFCSRFCross-Site Request Forgery跨站请求伪造是一种利用用户已登录状态发起非预期请求的攻击方式。CSRF攻击流程1. 用户登录正常网站A 2. 网站A设置登录Cookie 3. 用户在未退出的情况下访问恶意网站B 4. 恶意网站B发送请求到网站A 5. 浏览器自动带上Cookie 6. 网站A误以为是用户的正常请求CSRF攻击示例!-- 恶意网站上的图片标签 -- img srchttp://bank.com/transfer?toattackeramount1000 width0 height0 !-- 用户访问恶意网站时浏览器会自动发送请求 --CSRF防御策略1. 使用CSRF Token// 后端生成Token app.get(/csrf-token, (req, res) { const token generateToken(); req.session.csrfToken token; res.send(token); }); // 前端获取并使用Token const token await fetch(/csrf-token).then(res res.text()); // 在请求中带上Token fetch(/transfer, { method: POST, headers: { X-CSRF-Token: token, Content-Type: application/json }, body: JSON.stringify({ to: friend, amount: 100 }) }); // 后端验证Token app.post(/transfer, (req, res) { if (req.headers[x-csrf-token] ! req.session.csrfToken) { return res.status(403).send(Invalid CSRF token); } // 处理请求 });2. 使用SameSite Cookie// 设置SameSite属性 document.cookie sessionabc123; SameSiteStrict; // 或 document.cookie sessionabc123; SameSiteLax;3. 验证Referer头app.post(/transfer, (req, res) { const referer req.headers.referer; if (!referer || !referer.startsWith(https://yourdomain.com)) { return res.status(403).send(Invalid referer); } // 处理请求 });4. 使用双重验证// 对于敏感操作要求用户再次验证 async function transferMoney() { const password prompt(请输入密码确认转账); if (!password) return; const response await fetch(/transfer, { method: POST, headers: { Content-Type: application/json }, body: JSON.stringify({ to: friend, amount: 100, password }) }); }其他前端安全问题点击劫持!-- 恶意网站使用iframe嵌入目标网站 -- iframe srchttp://bank.com styleopacity:0; position:absolute; top:0; left:0; width:100%; height:100%/iframe !-- 用户点击时实际上点击的是iframe中的按钮 --防御!-- 设置X-Frame-Options -- meta http-equivX-Frame-Options contentDENY !-- 或使用JavaScript检测 -- if (window ! window.top) { window.top.location window.location; }敏感信息泄露// 不好的做法在前端存储敏感信息 localStorage.setItem(apiKey, sk-123456); // 好的做法只存储非敏感信息 localStorage.setItem(theme, dark);不安全的第三方库// 使用npm时检查依赖安全性 npm audit // 使用安全的CDN资源 script srchttps://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.production.min.js integritysha512-... crossoriginanonymous/script安全开发最佳实践1. 使用安全的框架和库// React会自动转义HTML function UserInput({ text }) { return div{text}/div; // 自动转义 } // Vue也会自动转义 p{{ userInput }}/p !-- 自动转义 --2. 实施安全的开发流程1. 代码审查每个PR必须经过安全审查 2. 自动化测试使用OWASP ZAP进行扫描 3. 安全培训定期进行安全培训 4. 漏洞响应建立漏洞上报和修复流程3. 使用安全工具# 使用ESLint进行安全检查 npm install eslint eslint-plugin-security # 使用npm audit检查依赖漏洞 npm audit # 使用Snyk进行持续安全监控 npx snyk test实战案例安全的评论系统// 安全的评论系统实现 class CommentSystem { constructor() { this.comments []; } addComment(userInput) { // 1. 输入验证 if (!userInput || userInput.length 1000) { throw new Error(Invalid comment); } // 2. 输出编码 const sanitizedInput this.sanitize(userInput); // 3. 添加到列表 this.comments.push({ id: Date.now(), content: sanitizedInput, timestamp: new Date() }); } sanitize(input) { // 使用DOMPurify清理 return DOMPurify.sanitize(input, { ALLOWED_TAGS: [b, i, u, a], ALLOWED_ATTR: [href] }); } renderComments() { const container document.getElementById(comments); container.innerHTML ; this.comments.forEach(comment { const div document.createElement(div); div.innerHTML comment.content; // 已经过清理 container.appendChild(div); }); } }总结前端安全是一个持续的过程需要我们时刻保持警惕。常见的XSS和CSRF攻击虽然可怕但只要采取正确的防御措施就能有效保护我们的应用和用户。我的鬃狮蜥Hash对安全也有自己的理解——它总是选择最安全的角落晒太阳远离可能的危险。这和我们做安全开发的道理是一样的。如果你有前端安全方面的问题欢迎留言交流我是欧阳瑞极客之路永无止境技术栈JavaScript · DOMPurify · CSP · OWASP