"用户信息被盗了!"周一早上,运营总监急匆匆地冲进办公室。原来是有用户反馈自己的账号在不知情的情况下被他人登录了。作为前端负责人,我立即组织团队开展安全排查。
这次事件让我们意识到,前端安全不容忽视。虽然之前也做过一些安全防护,但显然还不够完善。今天就来分享一下我们是如何系统性地提升前端安全性的。
漏洞排查
首先对系统进行全面的安全扫描,很快发现了几个典型的安全隐患:
// 案例一:XSS 漏洞
function CommentList({ comments }) {return (<div>{comments.map(comment => (// 危险:直接渲染用户输入的内容<div dangerouslySetInnerHTML={{ __html: comment.content }} />))}</div>)
}// 案例二:CSRF 漏洞
async function transferMoney(to, amount) {// 危险:没有验证请求来源const response = await fetch('/api/transfer', {method: 'POST',body: JSON.stringify({ to, amount })})return response.json()
}// 案例三:敏感信息泄露
const config = {apiKey: 'sk_live_xxxxx', // 危险:直接在前端暴露敏感信息apiEndpoint: 'https://api.example.com'
}
安全加固
1. XSS 防护
// 1. 输入过滤
function sanitizeInput(input) {return DOMPurify.sanitize(input, {ALLOWED_TAGS: ['b', 'i', 'em', 'strong'],ALLOWED_ATTR: ['title']})
}// 2. 安全的内容渲染
function CommentList({ comments }) {return (<div>{comments.map(comment => (<div key={comment.id}>{/* 使用 React 的自动转义 */}{comment.content}{/* 如果必须渲染 HTML,先进行过滤 */}<div dangerouslySetInnerHTML={{__html: sanitizeInput(comment.richContent)}} /></div>))}</div>)
}// 3. CSP 配置
// 在 HTML 中添加
<meta http-equiv="Content-Security-Policy"content="default-src 'self';script-src 'self' 'unsafe-inline' 'unsafe-eval';style-src 'self' 'unsafe-inline';">
2. CSRF 防护
// 1. 添加 CSRF Token
const csrfToken = document.querySelector('meta[name="csrf-token"]').contentasync function safeRequest(url, options = {}) {const response = await fetch(url, {...options,headers: {...options.headers,'X-CSRF-Token': csrfToken},// 自动带上 cookiecredentials: 'include'})if (!response.ok) {throw new Error('请求失败')}return response.json()
}// 2. 验证请求来源
app.use((req, res, next) => {const origin = req.get('Origin')const referer = req.get('Referer')// 验证请求来源if (!isValidOrigin(origin) || !isValidReferer(referer)) {return res.status(403).json({ error: '非法请求' })}next()
})
3. 敏感信息保护
// 1. 环境变量管理
// .env.production
VITE_API_ENDPOINT=https://api.example.com
VITE_PUBLIC_KEY=pk_live_xxxxx// 配置文件
const config = {apiEndpoint: import.meta.env.VITE_API_ENDPOINT,publicKey: import.meta.env.VITE_PUBLIC_KEY// 私钥等敏感信息只在服务端使用
}// 2. 本地存储加密
const storage = {set(key, value) {const encrypted = CryptoJS.AES.encrypt(JSON.stringify(value),STORAGE_KEY).toString()localStorage.setItem(key, encrypted)},get(key) {const encrypted = localStorage.getItem(key)if (!encrypted) return nullconst decrypted = CryptoJS.AES.decrypt(encrypted, STORAGE_KEY)return JSON.parse(decrypted.toString(CryptoJS.enc.Utf8))}
}
安全监控
为了及时发现安全问题,我们建立了安全监控系统:
class SecurityMonitor {constructor() {this.setupXSSMonitor()this.setupCSRFMonitor()this.setupSensitiveMonitor()}// 监控 XSS 攻击setupXSSMonitor() {// 监听 DOM 变化const observer = new MutationObserver(mutations => {mutations.forEach(mutation => {mutation.addedNodes.forEach(node => {if (node.nodeType === 1) {// 元素节点// 检查是否包含可疑的内联脚本const scripts = node.getElementsByTagName('script')Array.from(scripts).forEach(script => {if (this.isSupiciousScript(script)) {this.reportSecurityIssue('XSS', {script: script.innerHTML,url: window.location.href})}})}})})})observer.observe(document.body, {childList: true,subtree: true})}// 监控 CSRF 攻击setupCSRFMonitor() {const originalFetch = window.fetchwindow.fetch = async (url, options = {}) => {if (this.isRiskRequest(url, options)) {const hasToken = options.headers?.['X-CSRF-Token']if (!hasToken) {this.reportSecurityIssue('CSRF', {url,method: options.method})}}return originalFetch(url, options)}}// 监控敏感信息setupSensitiveMonitor() {// 监控控制台输出const originalConsole = { ...console }Object.keys(originalConsole).forEach(key => {console[key] = (...args) => {if (this.containsSensitiveInfo(args)) {this.reportSecurityIssue('SensitiveInfo', {type: 'console',args: this.maskSensitiveInfo(args)})}originalConsole[key](...args)}})}reportSecurityIssue(type, data) {// 发送安全告警fetch('/api/security/report', {method: 'POST',body: JSON.stringify({type,data,timestamp: Date.now(),url: window.location.href,userAgent: navigator.userAgent})})}
}
实践效果
通过这次安全加固:
- XSS 漏洞被完全修复
- CSRF 攻击得到有效防范
- 敏感信息得到妥善保护
- 安全事件响应更加及时
最让我印象深刻的是一位安全专家的评价:"这套防护体系已经达到了企业级应用的安全标准。"
经验总结
前端安全就像是给房子安装防盗系统,需要多层防护。关键是要:
输入过滤 - 永远不要信任用户输入访问控制 - 严格校验请求来源敏感防护 - 妥善保护敏感信息持续监控 - 及时发现安全隐患
写在最后
前端安全是一个持续的过程,需要我们不断学习和更新防护措施。就像那句话说的:"木桶的短板决定了水位的高度",任何一个安全漏洞都可能成为系统的致命弱点。
有什么问题欢迎在评论区讨论,让我们一起探讨前端安全的最佳实践!
如果觉得有帮助,别忘了点赞关注,我会继续分享更多实战经验~