sql注入原理是什么

 人参与 | 时间:2026-10-17 07:09:47
```html

一个登录框,入原你输入 ' or 入原'1'='1,密码随便填,入原居然进去了。入原这不是入原漏洞电影里的桥段,是入原二十年前很多网站的真实日常。SQL注入的入原本质就一句话:用户输入的数据被当成了SQL代码执行。

要理解这个事,入原得先知道后端在干嘛。入原你在前端填用户名和密码,入原点登录,入原浏览器把数据发给服务器。入原服务器上的入原程序通常会拼一条SQL语句去数据库里查:

SELECT * FROM users WHERE username = 'alice' AND password = '123456';

数据库收到这条指令,解析它,入原执行它,入原返回结果。正常流程就是这样。问题出在“拼”这个动作上。如果程序员偷懒,直接把用户输入的内容用字符串拼接塞进SQL里,那用户输入什么,数据库就执行什么。

拿刚才那个例子说。你在用户名框里输入 ' or '1'='1,密码框随便写个 x。程序拼出来的SQL变成:

SELECT * FROM users WHERE username = '' or '1'='1' AND password = 'x';

数据库一看,'1'='1' 永远为真,整个 WHERE 条件被短路了。AND password = 'x' 根本不起作用。查询返回所有用户记录,程序拿到第一条,认为登录成功。你进去了。

这还只是最基础的玩法。真正危险的是 UNION 注入。攻击者可以在输入里闭合前面的查询,再追加一条自己的查询,把数据库里其他表的数据带出来。比如:

' UNION SELECT username, password FROM admin_users --

两个短横线在SQL里是注释符,后面的原始语句直接被忽略。数据库执行的是攻击者构造的完整查询,结果里就包含了管理员账号密码。一次输入,整个用户表被拖走。

更极端的情况是堆叠注入。有些数据库驱动允许一次执行多条语句,攻击者可以用分号隔开,直接 DROP TABLE users。数据没了。这种事不是没发生过,2014年某国内电商平台就因为这个被拖库,几百万用户信息泄露。

为什么这种漏洞能活这么多年?两个原因。一是拼接字符串写起来太顺手了,新手教程里到处都是这种写法。二是很多老系统用的ORM框架或者数据库驱动默认不防注入,程序员不主动处理就出事。

防御手段其实很成熟。参数化查询是标准答案。你把SQL模板先发给数据库编译,再把用户输入作为参数传进去。数据库知道哪些是代码、哪些是数据,输入再奇怪也只会被当成字符串处理。Java里的 PreparedStatement、Python里的 cursor.execute(sql, params)、PHP里的PDO预处理,都是干这个的。

另一个常见做法是输入过滤。把单引号、分号、注释符这些敏感字符转义或者删掉。但这招不保险,不同数据库的转义规则不一样,编码绕过的手法层出不穷。宽字节注入、二次注入、盲注,攻击者总能找到缝隙。参数化查询才是根本解。

还有个细节容易被忽略:错误信息别直接吐给用户。数据库报错里经常带着表名、字段名、甚至部分SQL语句,攻击者靠这些信息就能摸清你的数据库结构。把错误日志写到服务器本地,前端只返回“系统繁忙”,能挡住很多试探。

我见过一个真实案例。某小型OA系统,登录接口用字符串拼接,管理员图省事没改。攻击者用 admin' -- 当用户名,密码空着,直接以管理员身份登录。进去之后发现数据库账号是root,整个服务器权限都拿到了。从发现漏洞到完全控制,不到十分钟。

SQL注入不复杂,原理一句话能说清。但它能造成的破坏,从数据泄露到服务器沦陷,跨度极大。写代码的时候多打几个字符用参数化查询,比事后补漏洞便宜太多。

``` 顶: 42踩: 54624