有人觉得注入是老掉牙的话题,现在框架都自带防护了。可实际渗透测试里,十次有六次还能从某个不起眼的参数钻进去,常见于自己写的查询、导出功能和报表筛选。这几条守得住吗?进场后怎么配合?
注入从哪进来
凡是把用户输入拼进SQL语句的地方都可能中。搜索框跟筛选条件和排序字段与分页参数。甚至URL里的id。开发者觉得"这个参数用户改不了",但请求是可以伪造的。最危险的是那些看起来不涉及查询的地方。
导出Excel时的条件、统计报表的时间范围和批量操作的id列表。这些功能往往写得仓促,过滤最松,反而成了突破口。防注入的根本办法是参数化查询,把SQL结构和数据分开,让用户输入永远当数据而不是语句。
参数化是根本办法
这一条做到位,注入基本无从下手。拼接字符串加转义函数是次优方案,容易漏。还有个细节:表名、字段名跟排序方向这些不能用参数化的地方,要用白名单。只允许预设的几个值,其他一律拒绝。靠黑名单过滤关键词是最不可靠的做法,绕过的写法太多了。
就算被注入,损失大小取决于数据库账号权限。用root跑业务。注入成功就能删库、读全表。用只具备必要权限的账号,能做的事就有限。这一层是末尾的安全垫。测试环境测不出来,是因为数据和权限跟生产不一样。
权限要收窄,别用高权限跑业务
建议在测试环境用接近生产的权限配置,并做一次简单的注入扫描。工具跑一遍不费什么时间。能发现大部分低级问题。收尾我提一句:注入不是技术难题,是习惯问题。参数化加白名单,两件事做到,就没什么可担心的。
SQL 注入防护的常见疑问
参数化查询能完全防注入吗
能防住绝大多数注入。表名、字段名等无法参数化的地方需配合白名单校验。
转义函数够用吗
不如参数化可靠,容易因为编码、字符集差异被绕过,建议优先参数化。
数据库账号怎么配
按业务需要授予最小权限,避免使用 root 或高权限账号连接业务库。
还有一条容易忘:错误信息别把 SQL 语句原样吐给前端。报错页面里带着表结构和查询逻辑,等于把数据库的地图送给了对方。统一成友好提示,细节只写进服务端日志。
总结:防注入靠两个习惯:参数化查询和白名单。再配合最小权限,风险就压下来了。