一、审计前准备(减少无效工作)
-
梳理项目架构与入口
- 拿到项目先看路由、控制器、接口清单:哪些是对外可访问接口,哪些需要登录 / 权限。重点标记:GET/POST 参数、文件上传、下载、回调接口、API 接口、定时任务。
- 确定技术栈:语言(Java/PHP/Python/Go)、框架(Spring、Laravel、Django)、数据库、中间件。框架自带安全机制要先了解,避免误报。
- 找到配置文件:数据库连接、密钥、JWT 配置、CORS、文件存储路径、白名单 / 黑名单。硬编码密钥、调试模式开启是常见高危。
-
确定风险清单 优先关注 OWASP Top10,按危害排序:注入、文件上传、命令执行、XSS、权限越权、SSRF、反序列化、敏感信息泄露。
二、核心审计方法:污点追踪(最有效)
污点:外部可控输入(HTTP 参数、Cookie、POST JSON、文件内容、第三方回调参数) 净化:输入经过严格过滤、转义、白名单校验
流程:污点源 → 传递 → 危险函数 / 危险操作(汇点)
-
找污点源:所有外部可控输入
- Java:
request.getParameter()、@RequestParam、@RequestBody - PHP:
$_GET/$_POST/$_REQUEST - Python:request.args、request.form
- Java:
-
沿着变量一路追踪:变量赋值、函数传参、对象属性赋值
-
判断是否进入危险汇点,且没有做净化
常见危险汇点举例
- SQL 注入:直接拼接 SQL,未使用预编译;ORM 框架原生拼接字符串
- 命令执行:
exec/system/popen,直接带入外部参数 - 文件操作:
file_get_contents、文件写入、文件路径拼接(路径穿越) - XSS:直接输出到页面,无 html 转义
- SSRF:
curl、http 客户端请求目标地址由外部传入 - 反序列化:
readObject、pickle.loads,反序列化不可信数据
重点提醒:不要只看危险函数,要看传入的参数是否可控,是否经过校验。很多调用危险函数,但参数是常量,不存在漏洞。
三、快速定位漏洞的技巧
1. 关键词搜索(最快初筛手段)
用 IDE/ripgrep 全局搜索危险函数、危险代码模式,批量定位候选代码块,再人工验证。 示例搜索词:
sql拼接:select.*+ , query(" + 命令执行:system|exec|popen|shell_exec 文件操作:file_get_contents|fopen|move_uploaded_file 反序列化:readObject|ObjectInputStream|pickle.loads XSS:echo|print|innerHTML
缺点:误报多,只用来缩小范围,不能直接判定漏洞。
2. 权限漏洞单独审计(非常容易漏)
越权(水平 / 垂直越权)很难靠关键词搜到,必须单独梳理:
- 接口校验逻辑:是否校验登录态?是否校验数据归属者?
- 查看修改数据时,是否用前端传的 ID 直接查询,没有从 session 拿用户 ID?
- 后台接口是否只做前端隐藏,后端没有权限判断。
3. 业务逻辑漏洞
这类漏洞没有危险函数,靠通读业务流程:
- 支付逻辑:金额、订单状态是否前端可控
- 验证码:验证码是否可复用、爆破、绕过
- 重置密码:是否可遍历用户、重置他人账号
- 重试、竞争条件(并发)问题
四、工具辅助(人为主,工具为辅)
-
SAST 静态扫描工具:SonarQube、Semgrep、CodeQL、GolangCI-lint、Seay 源码审计(PHP)
- CodeQL 适合自定义污点规则,大型项目首选;Semgrep 轻量,自定义规则简单。
- 作用:批量找危险函数、污点流,输出候选漏洞,必须人工复核消除误报
-
辅助工具:grep/ripgrep、IDE 全局查找、依赖扫描(SCA)
- SCA:检测第三方组件漏洞(依赖库 CVE),如 Dependency-Check、snyk
注意:SAST 有大量误报,也存在漏报;工具发现的只是 "可疑点",不等于漏洞。
五、审计流程标准化(提升效率)
- SCA 扫描:先扫第三方组件漏洞,组件漏洞经常比代码漏洞更容易利用
- SAST 初筛:工具输出可疑代码列表
- 人工污点审计:优先审计高危接口,按漏洞类型逐个验证可疑点
- 业务逻辑审计:单独梳理权限、支付、验证码等核心业务
- 漏洞复现:找到可疑代码后,搭建环境验证,确认可利用性,区分误报
- 整理报告:漏洞位置、漏洞原理、POC、修复建议
六、常见踩坑点
- 只找危险函数,不看变量来源:常量传入危险函数不算漏洞
- 忽略框架安全机制:比如 Spring 默认防 XSS、PDO 预编译防注入,不要重复报
- 漏了二次污染:输入经过多层函数传递,在后面的代码才进入危险汇点
- 忽略隐式污点:HTTP 头、User-Agent、IP、上传文件名称 / 内容也是可控输入
- 只关注主业务代码,忽略测试代码、后台管理接口、定时任务
七、不同语言审计侧重点
- PHP:文件上传、命令执行、SQL 拼接、路径穿越,代码零散,容易写裸 SQL
- Java/Spring:反序列化、权限越权、SSRF、Mybatis xml 拼接 SQL、Fastjson
- Python (Django/Flask):SSTI 模板注入、命令执行、ORM 原生 SQL、pickle 反序列化
- Go:SQL 拼接、文件路径穿越,框架本身安全能力较强,漏洞多在手写拼接逻辑