编写安全的JavaScript代码防止XSS攻击需遵循输入验证、输出转义、使用安全API和HTTP头防护的综合策略,具体措施如下:
一、输入验证与清理- 前端与后端双重验证:所有用户输入(如表单、URL参数、API数据)均需在前端和后端验证格式、长度、类型和字符集。例如,邮箱输入仅允许字母、数字、@和.。
- 白名单机制:通过正则表达式限制输入字符范围,如/^[a-zA-Z0-9@.]+$/过滤邮箱输入,拒绝非法字符。
- 避免直接使用用户输入:禁止将用户输入直接拼接至SQL查询或命令行参数中,防止命令注入。
二、输出转义与安全API- 优先使用textContent替代innerHTML:textContent会自动转义HTML标签(如<转为<),避免脚老慎本执行。例如:const userInput = '<script>alert(1)</script>';element.textContent = userInput; // 显示为文本,不执行脚本
- HTML净化库辩含信处理动态内容:若必须插入HTML(如富文本编辑器),使用DOMPurify等库净化内容:import DOMPurify from 'dompurify';const dirtyHtml = '<div onclick="alert(1)">User Content</div>';const cleanHtml = DOMPurify.sanitize(dirtyHtml); // 移除恶意标签element.innerHTML = cleanHtml;
- 上下文相关转义:
HTML内容:转义<、>、&为<、>、&。
属性值:转义引号("、')和空格,防止闭合标签注入。例如:const userInput = '" onclick="alert(1)"';element.setAttribute('title', userInput.replace(/"/g, '"'));
JavaScript字符串:拼接脚本时转义引号和换行符,如"、n。
三、利用现代框架的安全特性- React:
默认插值({variable})自动转义,但dangerouslySetInnerHTML需谨慎使用,必须配合净化库:function SafeComponent({ html }) { const cleanHtml = DOMPurify.sanitize(html); return <div dangerouslySetInnerHTML={{ __html: cleanHtml }} />;}
- Vue:
双大括号{{ }}自动转义,携轮v-html指令等同于innerHTML,应避免用于用户内容:<template> <div>{{ userInput }}</div> <!-- 安全 --> <div v-html="sanitizedHtml"></div> <!-- 需提前净化 --></template>
四、启用安全的HTTP头五、全链路安全实践- 不依赖客户端验证:客户端验证仅用于提升用户体验,后端必须重新验证所有输入。
- 定期安全审计:使用工具(如ESLint插件eslint-plugin-security)检测代码中的XSS风险。
- 最小权限原则:限制前端代码的DOM操作范围,避免全局事件监听器。
示例:完整防护流程// 1. 输入验证(前端示例)function validateEmail(email) { return /^[a-zA-Z0-9@.]+$/.test(email); // 简化版白名单}// 2. 输出转义(纯文本)function escapeHtml(str) { return str.replace(/[&<>'"]/g, (char) => ({ '&': '&', '<': '<', '>': '>', "'": ''', '"': '"' }[char]));}// 3. 安全插入HTML(结合DOMPurify)import DOMPurify from 'dompurify';const userInput = '<p>User Content</p><script>alert(1)</script>';const cleanHtml = DOMPurify.sanitize(userInput);document.getElementById('output').innerHTML = cleanHtml;// 4. 后端配合(Node.js Express示例)app.use(helmet({ contentSecurityPolicy: { directives: { defaultSrc: ["'self'"] } } }));app.use(cookieParser({ httpOnly: true, secure: true }));关键点总结:XSS防护需贯穿数据流全生命周期,从输入验证到输出转义,结合框架安全机制和HTTP头加固,形成多层次防御体系。