JavaScript安全防护指南:XSS防御与API加密实战
JavaScript安全防护实战指南:从XSS到加密API
1. XSS攻击与防御
概念解析
XSS(跨站脚本攻击)是攻击者向网页注入恶意脚本的攻击方式,主要分为三类:
- 存储型XSS:恶意脚本永久存储在服务器(如评论区)
- 反射型XSS:恶意脚本来自当前HTTP请求(如钓鱼链接)
- DOM型XSS:客户端脚本不安全地操作DOM
// 典型XSS示例
const userInput = "<script>alert('XSS')</script>";
document.getElementById("output").innerHTML = userInput;
防御方案
输入过滤:
function escapeHtml(unsafe) { return unsafe .replace(/&/g, "&") .replace(/</g, "<") .replace(/>/g, ">") .replace(/"/g, """) .replace(/'/g, "'"); }
- 输出编码:
- 文本内容:
textContent
代替innerHTML
- HTML属性:
setAttribute
代替字符串拼接 - URL参数:
encodeURIComponent
实践建议:
- 使用DOMPurify库净化HTML
- 在React中使用
dangerouslySetInnerHTML
时要特别小心 - 在Vue中使用
v-html
指令时确保内容可信
2. CSRF防护
SameSite Cookie属性
SameSite三种模式:
Strict
:完全禁止第三方CookieLax
:允许安全方法(GET)的顶级导航None
:允许所有(需配合Secure)
CSRF Token机制
// 服务端生成并存储Token
const csrfToken = crypto.randomBytes(32).toString('hex');
sessionStorage.setItem('csrfToken', csrfToken);
// 客户端发送请求时携带
fetch('/api/transfer', {
method: 'POST',
headers: {
'X-CSRF-Token': csrfToken
}
});
实践建议:
- 关键操作使用POST/PUT/DELETE方法
- 重要Cookie设置HttpOnly+SameSite
- 敏感操作增加二次验证
3. CSP内容安全策略
基础配置示例
Content-Security-Policy:
default-src 'self';
script-src 'self' 'unsafe-inline' cdn.example.com;
style-src 'self' 'unsafe-inline';
img-src * data:;
connect-src https://api.example.com;
frame-ancestors 'none';
form-action 'self';
关键指令说明
指令 | 作用 | 推荐值 |
---|---|---|
script-src | 控制JS加载源 | 'self' 非必要不用'unsafe-inline' |
style-src | 控制CSS加载源 | 'self' 'unsafe-inline' |
connect-src | 限制AJAX请求源 | 明确API域名 |
report-uri | 违规报告地址 | 生产环境建议配置 |
实践建议:
- 逐步实施CSP:先使用
Content-Security-Policy-Report-Only
- 使用nonce或hash替代'unsafe-inline'
- 禁止内联事件处理程序(如onclick)
4. 沙箱机制(Sandbox)
iframe沙箱实现
<iframe
sandbox="allow-scripts allow-same-origin"
src="untrusted.html"
></iframe>
可用权限:
allow-forms
:允许表单提交allow-popups
:允许弹出窗口allow-scripts
:允许执行脚本allow-same-origin
:保留同源策略
Web Worker沙箱
// 主线程
const worker = new Worker('untrusted.js');
// untrusted.js
self.onmessage = (e) => {
// 受限环境,无法访问DOM
const result = heavyCalculation(e.data);
postMessage(result);
};
实践建议:
- 第三方组件使用Shadow DOM隔离
- 插件系统采用Worker沙箱
- 动态代码使用
new Function()
而非eval
5. 加密API(Web Crypto)
常见操作示例
生成密钥对:
const keyPair = await crypto.subtle.generateKey(
{
name: "RSA-OAEP",
modulusLength: 2048,
publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
hash: "SHA-256"
},
true,
["encrypt", "decrypt"]
);
数据加密:
const encrypted = await crypto.subtle.encrypt(
{
name: "RSA-OAEP"
},
publicKey,
new TextEncoder().encode("敏感数据")
);
哈希计算:
const hashBuffer = await crypto.subtle.digest(
'SHA-256',
new TextEncoder().encode('待哈希数据')
);
const hashArray = Array.from(new Uint8Array(hashBuffer));
const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
实践建议:
- 前端加密不能替代HTTPS
- 密码存储使用PBKDF2等慢哈希算法
敏感操作使用时间安全比较
// 安全比较 function safeCompare(a, b) { const aBuf = new TextEncoder().encode(a); const bBuf = new TextEncoder().encode(b); if (aBuf.length !== bBuf.length) return false; let result = 0; for (let i = 0; i < aBuf.length; i++) { result |= aBuf[i] ^ bBuf[i]; } return result === 0; }
综合防御策略
深度防御原则:
- 输入验证 + 输出编码 + 运行时防护
- 前端防护 + 后端校验
安全头配置:
X-Content-Type-Options: nosniff X-Frame-Options: DENY X-XSS-Protection: 1; mode=block Referrer-Policy: strict-origin-when-cross-origin
监控与响应:
- CSP违规报告收集
- 关键操作日志审计
- 定期安全扫描
通过组合这些安全措施,可以构建多层次的JavaScript应用防护体系,有效抵御常见Web攻击。记住:安全不是一次性的工作,而是需要持续关注和改进的过程。
评论已关闭