<p>确认API是否拼接SQL,先检查代码或文档中是否存在String sql = "SELECT * FROM users WHERE id = " + id;等直接字符串拼接写法;Java用Statement、PHP用mysql_query()或mysqli_query()、Python用cursor.execute()拼接即高危;若使用PreparedStatement、参数化查询或ORM的.filter()方法则基本安全。</p>

怎么确认API是否在用拼接SQL
别急着上工具,先看代码或文档里有没有 String sql = "SELECT * FROM users WHERE id = " + id; 这类写法。Java里是 Statement,PHP里是 mysql_query() 或 mysqli_query() 直接拼字符串,Python里是 cursor.execute("SELECT * FROM ... WHERE id = " + user_id) ——这些就是高危信号。如果用了 PreparedStatement、parameterized query 或 ORM 的 .filter() 方法,基本排除拼接风险。
抓包看参数是否进SQL执行路径
用 Burp Suite 或浏览器开发者工具拦截请求,重点观察:参数是不是直接出现在 SQL 日志里(比如数据库慢查询日志)、返回体里有没有数据库错误堆栈(如 MySQLSyntaxErrorException)、HTTP 状态码是不是 500 且响应含 SQL syntax 或 ORA- 前缀。常见陷阱是:前端传了 {"id": "1' OR '1'='1"},后端没做任何校验就塞进 WHERE 条件,结果数据库报错并回显——这就是典型可利用点。
用SQLMap精准打POST/PUT接口的技巧
REST API 多数走 JSON body,SQLMap 默认不处理,必须手动指定:
- 加
--method POST或--method PUT,不能依赖自动识别 - 用
--data '{"user_id":1}'显式提供原始 body,别用-d - 必须配
--content-type "application/json",否则服务端可能拒收 - 如果参数在 URL 路径里(如
/users/1),得用*占位:-u "https://api.example.com/users/*/profile" --method GET
漏掉任意一项,SQLMap 就会发错格式的请求,返回 400 或 415,根本测不到漏洞。
为什么WAF日志里没报但仍有注入风险
很多 WAF 只拦常见关键词(union select、sleep(),但绕过手段极多:base64 编码 payload、用 /*!50000union*/ 注释混淆、拆成多个请求分段传输。更麻烦的是,有些注入点只在特定业务逻辑下触发(比如“修改密码”接口要先校验旧密码,旧密码字段若拼接 SQL,就得先登录再测)。单纯看 WAF 日志会漏掉大量真实风险。


















