$npx -y skills add 0xShe/PHP-Code-Audit-Skill --skill php-sql-auditPHP Web 源码 SQL 注入漏洞审计工具。从源码中识别所有 SQL 执行点并分析注入风险,输出可利用性分级、PoC 与修复建议(禁止省略)。
| 1 | # PHP SQL 注入审计(php-sql-audit) |
| 2 | |
| 3 | 分析 PHP 项目源码,识别 SQL 执行相关代码(PDO/mysqli/ORM),追踪用户输入到 SQL 构造点,验证是否存在 SQL 注入,并输出完整漏洞报告。 |
| 4 | |
| 5 | ## CRITICAL:禁止省略与禁止误报 |
| 6 | - 必须审计所有在路由参数中出现的字符串来源(GET/POST/Body/参数字段)进入 SQL 的路径 |
| 7 | - 必须使用“数据流追踪证据”判定可利用性;不得只靠关键字猜测 |
| 8 | - 禁止省略:不得出现任何省略占位符;必须输出完整的漏洞证据链与修复建议 |
| 9 | |
| 10 | ## 分级与编号 |
| 11 | - 详见:`shared/SEVERITY_RATING.md` |
| 12 | - 漏洞编号:`{C/H/M/L}-SQL-{序号}` |
| 13 | |
| 14 | ## 输入依赖 |
| 15 | 建议至少有(与 `shared/IO_PATH_CONVENTION.md` 一致;合并流水线时读总报告中等价章节即可): |
| 16 | - `routes_{timestamp}.md`(独立落盘时常为 `route_mapping/routes_{timestamp}.md`) |
| 17 | - `params_{timestamp}.md`(独立落盘时常为 `route_mapping/params_{timestamp}.md`) |
| 18 | 可选但推荐: |
| 19 | - `route_tracer/` 输出,用于精准判定参数实际使用状态 |
| 20 | |
| 21 | ## SQL Sink 识别(必做) |
| 22 | 1. PDO / PDOStatement |
| 23 | - 相对危险:`$pdo->query($sql)` / `$pdo->exec($sql)`(若 $sql 来自拼接/包含用户输入) |
| 24 | - 形式检查:`$pdo->prepare($sql)` 只有在 `$sql` 中使用占位符且后续 `bindParam/bindValue` 或正确传参时更安全 |
| 25 | - ORM/DB 包装:`DB::select(DB::raw({value}))`、Doctrine `createQuery` 等 |
| 26 | 2. mysqli / mysqli_stmt |
| 27 | - `mysqli_query($conn, $sql)` 拼接危险 |
| 28 | - `mysqli_prepare` 只有 prepare + bind 正确时才可能安全 |
| 29 | 3. 典型危险构造模式(必做) |
| 30 | - SQL 字符串与变量拼接:`.`, `sprintf`, `vsprintf`, `implode/join` + SQL 关键字 |
| 31 | - 动态排序:`order by $x` / `ORDER BY ".$x."`(常见高危) |
| 32 | |
| 33 | ## 需要触发 tracer 的条件(必做) |
| 34 | 满足任一条时必须调用 `php-route-tracer`(或同等追踪证据): |
| 35 | - 参数经过多层传递或 JSON 解码后取字段进入 SQL |
| 36 | - SQL 构造点位于基类/工具类/父函数中 |
| 37 | - 存在分支条件(if/try/catch)导致 SQL 是否执行不确定 |
| 38 | |
| 39 | ## 报告输出 |
| 40 | 输出到: |
| 41 | ``` |
| 42 | {output_path}/vuln_audit/ |
| 43 | └── sql_{timestamp}.md |
| 44 | ``` |
| 45 | |
| 46 | ## 漏洞报告条目模板(强制) |
| 47 | ```markdown |
| 48 | ### [{等级前缀}-SQL-{序号}] {风险标题} |
| 49 | |
| 50 | | 项目 | 信息 | |
| 51 | |------|------| |
| 52 | | 严重等级 | {🔴/🟠/🟡/🔵} (CVSS {score}) | |
| 53 | | 可达性 (R) | {0-3} - {理由} | |
| 54 | | 影响范围 (I) | {0-3} - {理由} | |
| 55 | | 利用复杂度 (C) | {0-3} - {理由} | |
| 56 | | 可利用性 | ✅ 已确认 / ⚠️ 待验证 / ❌ 不可利用 / 🔍 环境依赖 | |
| 57 | | 位置 | {file}:{line} ({Function/Class}) | |
| 58 | |
| 59 | #### 数据流链(Source → Sink) |
| 60 | (按路由逐行写出:请求参数读取 -> 变量赋值/拼接/转换 -> 分支 -> SQL 进入执行点。禁止省略) |
| 61 | |
| 62 | #### 可利用前置条件 |
| 63 | - 鉴权要求:{无需/需登录/需特定权限} |
| 64 | - 输入可控性:{完全可控/条件可控/不可控} |
| 65 | - 触发条件:{分支/异常/环境依赖} |
| 66 | |
| 67 | #### 证据引用(强制:来自 php-route-tracer) |
| 68 | 每条 SQL 疑似漏洞必须逐项引用 trace 输出中 `## 9) Sink Evidence Type Checklist` 的 **SQL 行**对应证据要点(允许状态为待验证,但证据引用必须存在): |
| 69 | 1. `EVID_SQL_EXEC_POINT`:SQL 执行函数/语句位置(对应 trace 的 SQL 执行点证据) |
| 70 | 2. `EVID_SQL_STRING_CONSTRUCTION`:SQL 字符串构造/拼接位置(对应 trace 的 SQL 拼接证据) |
| 71 | 3. `EVID_SQL_USER_PARAM_TO_SQL_FRAGMENT`:用户可控参数到 SQL 片段的映射(对应 trace 的可控性矩阵字段证据) |
| 72 | |
| 73 | #### tracer 证据缺失处理(强制) |
| 74 | - 若无法定位上述 1~3 任一关键证据要点:该漏洞状态只能标记为 `⚠️待验证`,不得直接给出 `✅已确认可利用`。 |
| 75 | |
| 76 | #### 验证 PoC(强制,可执行请求) |
| 77 | ```http |
| 78 | {HTTP Method} {完整路径与查询/Body} HTTP/1.1 |
| 79 | Host: {host} |
| 80 | {必要 Header/Session/JWT/Cookie} |
| 81 | |
| 82 | {Payload} |
| 83 | ``` |
| 84 | |
| 85 | #### 建议修复 |
| 86 | - 给出安全写法要点(PDO prepare + bind 且保证 SQL 片段不拼接用户输入) |
| 87 | - 给出代码搜索语句(`rg`/`grep` 风格)用于定位所有同类拼接点 |
| 88 | ``` |
| 89 | |
| 90 | ## 输出完整性检查(强制) |
| 91 | - [ ] 至少输出:风险统计 + 每条漏洞完整条目 |
| 92 | - [ ] 不出现任何省略占位符 |
| 93 | - [ ] 每条漏洞都包含:数据流链、可利用前置条件、可执行 PoC、修复建议 |