代码层面规避web通用漏洞
字数 1336 2025-08-09 15:23:15
Web通用漏洞代码层面规避指南
服务端安全防护
1. 身份认证安全
封装错误信息
- 危险做法:明确区分用户名错误和密码错误
// 错误示例
if (!existingUser) {
return res.status(401).json({errorMessage: "Invalid email."});
}
if (!passwordCorrect) {
return res.status(401).json({errorMessage: "Password is invalid for the given email."});
}
- 正确做法:统一返回模糊错误信息
// 正确示例
if (!existingUser || !passwordCorrect) {
return res.status(401).json({errorMessage: "Invalid email or password."});
}
用户标识
- 使用服务端随机生成的唯一标识,避免用户自定义
- 采用非连续ID,降低遍历风险
邮箱验证
- 正则验证格式 + 检查MX记录
import dns.resolver
import re
def checkEmailValid(email):
if re.search('\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b', email):
domain = email.split("@")[1]
for _ in dns.resolver.query(domain, 'MX'):
return True
return False
密码安全
- 强制实施强密码策略
- 必须使用哈希函数(如bcrypt)存储,而非加密
验证码
- 增加暴力破解成本的有效手段
日志监控
- 记录以下关键事件:
- 认证错误日志
- 登录失败记录
- 账户锁定事件
2. 目录遍历防护
漏洞成因
- 用户输入被直接拼接至文件路径
String path = BASE_PATH + request.getParameter("folder") + request.getParameter("file");
防护措施
- 验证规范化后的路径是否在允许范围内
String canonicalPath = file.getCanonicalPath();
if(!canonicalPath.startsWith(BASE_PATH)) {
throw new GenericException("Access denied.");
}
3. 文件上传安全
防护方案
- 最佳实践:使用CDN/云存储服务
- 本地存储时的防护:
- 文件重命名为随机名称
- 存储目录配置无执行权限
file_f = os.open("/path/to/file", os.O_WRONLY | os.O_CREAT, 0o600)- 扩展名和MIME类型白名单验证
- 验证文件实际内容类型
- 限制文件大小防DoS
4. Host头注入防护
危险示例
String host = request.getHeader("Host");
String resetLink = host + "?reset" + token; // 直接拼接Host头
防护措施
- 优先使用相对路径URL
- 必须使用绝对路径时,从配置文件读取域名
- 配置允许的域白名单
5. 命令注入防护
危险示例
os.system("cat " + file) # 直接拼接用户输入
防护措施
- 使用语言内置函数替代系统命令
os.mkdir(dir_name) # 替代os.system("mkdir " + dir_name) - 必须调用系统命令时:
- 转义所有参数
- 最小权限运行
- 命令白名单限制
6. SSRF防护
漏洞利用协议
http://- 探测内网gopher://- 发送GET/POST请求dict://- 泄露软件信息file://- 读取本地文件
防护措施
- 设置请求域白名单
- 从配置读取API地址而非用户输入
- 网络层出站请求限制
- 内网隔离
7. SQL注入防护
危险示例
sql = "SELECT * FROM users WHERE email='" + email + "' AND password='" + password + "'"
防护措施
- 参数化查询
cursor.execute("SELECT * FROM users WHERE email=%s AND password=%s", [email, password])
- 验证数据类型和长度
8. XXE防护
漏洞成因
- 解析外部实体导致文件读取/SSRF
防护措施
- 禁用DTD和外部实体解析
parser = etree.XMLParser(resolve_entities=False) # 禁用实体解析
客户端安全防护
1. 点击劫持防护
防护措施
- 设置X-Frame-Options响应头:
DENY- 禁止任何框架嵌套SAMEORIGIN- 仅允许同源嵌套ALLOW-FROM URI- 允许指定源嵌套
- 使用CSP策略:
Content-Security-Policy: frame-ancestors 'none'
2. CSRF防护
防护措施
- 遵循RESTful规范:状态修改使用POST/PUT/DELETE
- CSRF Token验证
<input type="hidden" name="_csrf" value="{{csrfToken}}">
- 关键操作添加验证码
- 验证Referer头
3. 开放跳转防护
危险示例
response.sendRedirect(request.getParameter("url")); // 直接跳转用户输入
防护措施
- 避免使用重定向
- 必须使用时:
- 验证目标URL有效性
- 使用URL白名单
- 添加中间确认页面
4. Session劫持防护
防护措施
- 设置HttpOnly Cookie属性
- Session ID仅通过Cookie传输,禁止URL传递
5. XSS防护
存储型XSS防护
- 转义所有动态内容
- 启用CSP策略
Content-Security-Policy: script-src 'self'
反射型XSS防护
- 同存储型XSS,转义所有来源的动态内容
DOM型XSS防护
- 避免直接将用户输入插入DOM
- 使用
textContent替代innerHTML
document.getElementById('elem').textContent = userInput; // 安全
总结
- 输入验证:所有用户输入必须验证和过滤
- 输出编码:动态内容输出前必须编码
- 最小权限:应用运行和资源访问使用最小权限
- 安全配置:框架和服务器安全配置到位
- 纵深防御:多层防护措施叠加
通过实施以上代码层面的安全措施,可有效防范绝大多数Web通用漏洞。