登录页输入框里填一段奇怪字符,账号密码都不对,居然进了后台。这类事故的根子只有一个:程序把用户输入当成了 SQL 语句的一部分。sql注入攻击的原理说穿了就一句话,输入变成了代码。被利用的后果不只是登录,轻则读到别人的订单,重则整库数据被带走。

拼接字符串那一刻就输了

正常的查询长这样:select * from users where name = 输入的用户名。程序用字符串拼接的方式,把用户输入原样塞进引号里。输入里带上单引号和逻辑条件,引号提前闭合,后面的内容就被数据库当成 SQL 代码执行。拼接的地方越多,口子越大。

数字型参数也一样危险

地址栏里的 id=1,直接拼进 where id = 1,没有引号包着,一样能塞进额外条件。很多人只防字符串字段,忘了数字参数,结果从排序字段、分页参数这些地方被突破。order by 后面拼字段名,更是重灾区。联合查询、报错注入、盲注这些说法,本质上都是同一个入口,只是回显方式不同。

参数化查询是正解

预编译语句把 SQL 结构和数据分开传,数据库先解析好语句,再把参数当纯数据填进去,输入里有什么符号都不起作用。PHP 的 PDO、Java 的 PreparedStatement、Python 的占位符,用法不同,思路一样。能参数化的地方全部参数化,别自己拼。输入长度也限一下,比如用户名不超过 32 个字符,很多试探就进不来。

剩下的都是补丁

字段类型做白名单校验,比如排序只允许几个固定列名;数据库账号只给必要的权限,别用 root 连业务库;报错信息不要回显到页面,错误码统一处理。ORM 里的原生 SQL 拼接同样要查,别以为用了框架就安全。WAF 能挡常见扫描,但绕过手法一直有。数据库账号按读写分开,报表和后台各用一个,出事时损失能小一圈。

sql注入攻击的原理 说到底就是数据混进了代码,参数化查询把这个通道堵死,才算真的解决。老项目改造时优先查登录、搜索、导出这三类接口,输入多、拼接多,出事概率最高。日志里正则匹配一下异常的关键词,能提前发现试探。