// Express中间件:全局XSS防护
const xss = require('xss');
app.use((req, res, next) => {
// 对所有请求参数进行过滤
req.cleanedParams = xss(req.params);
req.cleanedQuery = xss(req.query);
req.cleanedBody = xss(req.body);
next();
});
// React组件安全渲染示例
function SafeComponent({ userInput }) {
// 使用dangerouslySetInnerHTML需谨慎
return (
{/* 静态内容直接渲染 */}
{userInput}
{/* 动态内容必须经过转义 */}
);
}
// 自定义转义函数
function escapeHtml(str) {
return str.replace(/[&<>"']/g, (match) => ({
'&': '&',
'<': '<',
'>': '>',
'"': '"',
"'": '''
})[match]);
}
// Express CSRF保护配置
const csrf = require('csurf');
const csrfProtection = csrf({ cookie: true });
app.use(csrfProtection);
// AJAX请求携带CSRF Token示例
fetch('/api/submit', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRFToken': document.querySelector('meta[name="csrf-token"]').getAttribute('content')
},
body: JSON.stringify(formData)
});
// CSRF Token meta标签配置
# Nginx CORS安全配置示例
server {
location /api {
add_header 'Access-Control-Allow-Origin' 'https://trusted-domain.com';
add_header 'Access-Control-Allow-Methods' 'GET,POST,PUT,DELETE';
add_header 'Access-Control-Allow-Headers' 'Origin,X-Requested-With,Content-Type,Authorization';
# 限制预检请求频率
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=1r/s;
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Length' 0;
return 204;
}
}
}
Content-Security-Policy:
default-src 'self';
script-src 'self' https://trusted-cdn.com;
object-src 'none';
style-src 'self' 'unsafe-inline';
// 密码哈希存储示例(Node.js)
const bcrypt = require('bcrypt');
const saltRounds = 12;
async function hashPassword(password) {
// 生成盐值
const salt = await bcrypt.genSalt(saltRounds);
// 加密密码
return await bcrypt.hash(password, salt);
}
// 密码验证
async function comparePassword(userPassword, hashedPassword) {
return await bcrypt.compare(userPassword, hashedPassword);
}
# Flask文件上传验证中间件
from werkzeug.utils import secure_filename
import os
def allowed_file(filename):
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif'}
return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
@app.route('/upload', methods=['POST'])
def upload_file():
file = request.files['file']
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
else:
return 'Invalid file type', 400
// 不安全的会话管理(前端存储Token)
localStorage.setItem('authToken', response.data.token);
// 改进方案:使用HttpOnly Cookie
Set-Cookie: authToken=xyz; HttpOnly; SameSite=Lax
# 使用npm audit检查依赖漏洞
npm audit
# Snyk监控示例
snyk test
snyk monitor
# ModSecurity规则集配置
location / {
modsecurity on;
modsecurity_rules_file /etc/modsecurity/owasp-crs/ruleset.xml;
# 防御SQL注入
SecRule REQUEST_URI|ARGS|REQUEST_BODY "@sql_injection" \
"id:900001,\
phase:2,\
block,\
t:none,\
log,\
msg:'SQL Injection Attack Detected'"
}
// Prometheus + Grafana监控配置
const client = new Prometheus({
register: new Registry(),
prefix: 'web_security'
});
// 记录CSRF攻击尝试
client.gauge('csrf_attempt_count', {
label: ['status']
}).inc({ status: 'blocked' });
// 设置报警规则
groups: [{
name: 'Web Security',
rules: [{
alert: 'High CSRF Attempt Rate',
expr: 'rate(web_security_csrf_attempt_count[5m]) > 10',
for: '10m',
labels: { severity: 'critical' }
}]
}]
# 新人安全开发checklist
- [ ] 任何用户输入必须进行过滤/转义
- [ ] 所有API请求必须验证CSRF Token
- [ ] 敏感数据禁止使用LocalStorage存储
- [ ] 文件上传必须包含文件类型验证
- [ ] 密码必须使用bcrypt等强哈希算法
通过建立多层防护体系(从输入验证到监控报警),结合自动化安全工具链,可以有效降低Web应用面临的安全风险。关键是要形成安全开发的肌肉记忆,在每个环节都主动考虑防御措施,而不是依赖后期补救。