代码审计:如何在全新编程语言中发现漏洞?
字数 1354 2025-08-12 11:34:21
全新编程语言中的漏洞发现与代码审计指南
一、安全标准不一致问题
1.1 中间件与应用程序标准不一致
案例:WSGI与中间件解析差异
- 当中间件(如nginx)和应用程序桥接器(如gunicorn)对请求解析标准不同时
- 攻击示例:构造
/privateHTTP/1.1/../../public- nginx解析为访问
/public并放行 - gunicorn解析为两个请求(
/private和/public) - 绕过安全检查
- nginx解析为访问
1.2 数据类型安全标准不一致
案例:NoSQL注入
- 不同语言对数据类型的处理方式不同
- 攻击示例:
/login?username=admin&password['$ne']=1- 被解析为MongoDB查询:
db.Users.find({username:'admin',password:{'$ne':'1'}}) $ne操作符使密码不为1即可登录成功
- 被解析为MongoDB查询:
1.3 多种注入防御机制冲突
案例:XSS与SQL防御冲突
- XSS防御:删除所有HTML标签
- SQL防御:删除黑名单关键字
- 绕过方法:在关键字中插入
<a>标签- 例如:
<a>SELECT<a>可能绕过两种防御
- 例如:
二、代码与数据边界问题
2.1 不安全的模板渲染
案例:模板注入
- 开发者已对每个变量进行安全限制
- 攻击方法:
- 在user变量输入:
)/* - 在punc变量输入:
*/任意无字母数字shell?> - 使punc从数据变为可执行代码
- 在user变量输入:
2.2 跨语言数据传递漏洞
案例:YAML反序列化
- YAML用于存储配置或跨语言数据传输
- 攻击方法:覆盖YAML文件为恶意内容
- 示例:构造反弹shell的YAML配置
三、可预测的安全处理方式
3.1 输入矫正漏洞
案例:CVE-2022-30333(unRAR漏洞)
- 安全限制:阻止
../等目录穿越 - 漏洞成因:将
\转换为/的人性化处理..\被转换为../绕过检查- 导致任意目录文件写入
3.2 不安全过滤机制
案例:SQL注入过滤绕过
- 双写绕过:
oorr被过滤为or后仍有效 - 输入示例:
' oorr 1=1#
3.3 可预测的密钥
案例:Flask session密钥
- 使用主机名作为加密密钥
- 攻击者获取主机名后可伪造任意session
- 导致全面控制用户和管理员账户
四、意外的可控变量
4.1 变量存储位置问题
案例:二次注入
- 变量存储在多个位置(如数据库和session)
- 攻击方法:
- 在session中存储
' or 1=1# - 绕过安全检查修改所有用户密码
- 在session中存储
4.2 误判变量可控性
案例:User-Agent注入
- 开发者认为User-Agent不可控
- 实际可通过HTTP头修改
- 导致注入漏洞
审计方法论总结
- 检查接口标准一致性:关注语言与中间件、数据库等交互时的解析差异
- 验证数据与代码边界:特别关注模板渲染、序列化/反序列化过程
- 测试安全处理可预测性:尝试绕过过滤和矫正机制
- 寻找隐藏的可控点:检查所有可能的输入源,包括非常规变量
关键审计技巧
- 构造边界测试用例(如
../与..\) - 测试数据类型转换行为(如字符串到数组)
- 验证所有防御机制的交互效果
- 检查变量存储的多个位置
- 测试非常规输入点(User-Agent等)