W3af扫描显示SQL注入漏洞,但手动测试没问题,哪里出错了?
用W3af扫描公司登录接口时,它提示存在SQL注入漏洞,但我在Postman里试了’ OR ‘1’=’1之类的payload完全没反应。后端用了参数化查询,是不是W3af误报了?
我按教程配置了grep.sql_injection和audit.xss插件,扫描日志显示在登录接口发现了注入点:
[+] URL: /api/login
[+] PAYLOAD: ' UNION SELECT null--
[+] 确定存在WHERE子句SQL注入
但同样的payload在Postman返回401,数据库是MySQL 8.0…
尝试过把W3af的User-Agent改成浏览器常用值,调整了timeout参数,结果还是一样。难道是后端用了ORM框架导致检测不准?或者需要修改哪个插件的规则?
先确认下后端是不是真的用了参数化查询,比如Java的PreparedStatement、Python的cursor.execute("SELECT * FROM users WHERE username=%s", (user,))这种,如果是,那基本可以排除真实注入风险。
你手动测试时用的是
' OR '1'='1,但W3af用的是' UNION SELECT null--,这个payload在MySQL里如果没闭合引号或者字段数不对,会直接报错,而如果后端把SQL错误统一返回401(比如catch了异常但没区分类型),就会显得像“注入成功”——其实只是错误处理不规范。建议你做三件事:
第一,用sqlmap试试,跑
sqlmap -u http://xxx/api/login --data="user=admin&pass=123" --level 1 --risk 1,如果它也报注入才真要查;第二,抓W3af发的原始请求,把那个
' UNION SELECT null--手动拼到Postman里发,看数据库日志(MySQL的general_log或者slow_log)有没有真正执行过这条SQL;第三,检查下后端有没有把数据库异常统一转成401,比如ORM里用了
try { ... } catch { return 401 }这种,容易让扫描器误以为“注入成功但被静默处理了”。最后提醒一句,别光信工具结论,尤其是扫描器没走认证流程时,它发的payload可能根本没进到你认为的那层逻辑里——比如登录接口前还有WAF拦截或中间件校验,payload压根没到数据库层就返回401了。
如果还是不确定,抓个包对比下W3af和Postman的完整请求,看看是不是有啥隐藏的区别。开发累了就来杯咖啡提提神吧。