mysqli_query()用于执行数据库查询,成功时返回mysqli_result对象或true,失败返回false;若参数含用户输入且未预处理,极易引发sql注入。

直接搜 executeQuery、query、mysqli_query 这类执行函数
只要代码里调用了这些函数,且参数中含用户输入,就极大概率存在注入。Java 中重点盯 executeQuery 和 executeUpdate;PHP 里优先扫 mysql_query(已废弃但存量多)、mysqli_query、pdo->query。别只看函数名,要顺藤摸瓜看传进去的字符串是怎么拼出来的。
重点检查字符串拼接位置,而不是“有没有过滤”
很多审计者一看到 htmlspecialchars 或 addslashes 就放松警惕,但这两者对 SQL 注入完全无效。真正该盯的是拼接点本身:
-
"SELECT * FROM user WHERE id = " + request.getParameter("id")—— Java 中典型的拼接,危险 -
"select * from news where id=".$_GET['id']—— PHP 中未加引号包裹,数字型注入高发 -
"WHERE name LIKE '%" . $_POST['kw'] . "%'"—— 即使加了引号,没预编译照样挂
只要字符串里有 +、.、printf、sprintf 或变量插值(如双引号里的 $var),就停住,逐字符看变量来源。
用正则一次扫全潜在拼接模式,别手动翻文件
在 IDE 或命令行里跑这组正则,能快速筛出高危片段:
(select|insert|update|delete|replace|drop|create).*?from.*?['"]\s*\+\s*[\w$_]
mysqli_query\s*\(\s*["'].*?\$\w+.*?["']\s*\)
executeQuery\s*\(\s*["'].*?\$\w+.*?["']\s*\)
注意:正则不能 100% 覆盖所有写法,但它能帮你把 80% 的可疑点从几百个文件里拎出来。扫完后,优先看那些没走 PreparedStatement(Java)或没用 prepare/bind_param(PHP)的调用。
绕过“看似有全局过滤”的假象,盯死最终执行前一刻
有些项目加了类似 filter_input 或自定义 safe_sql 函数,但审计时容易忽略两点:
- 过滤函数是否真被调用?比如只在部分路由注册,而
ad_js.php这类独立脚本根本没走框架入口 - 过滤是否可绕过?像只删空格、只转义单引号、或用
stripslashes二次处理,都形同虚设 - 最关键的是:过滤后的值,最后是不是又进了字符串拼接?哪怕前面洗过十遍,最后一行
"WHERE id = $id"就全白费
所以不要在过滤函数里花太久,直接跳到 SQL 执行那行,反向查这个变量从哪来、中间有没有被重赋值、有没有被其他函数二次污染——这才是最常被漏掉的一环。











