sql注入是什么意思
你打开一个网站,意思在搜索框里输入一串看似乱码的意思字符,点击搜索。意思下一秒,意思网站返回了所有用户的意思账号密码。这不是意思电影桥段,是意思SQL注入最直白的演示。
SQL是意思Structured Query Language的缩写,一种用来跟数据库对话的意思语言。网站背后几乎都挂着数据库,意思存着用户信息、意思商品订单、意思文章内容。意思当你在页面上操作时,意思程序会把你的意思操作翻译成SQL语句,发给数据库执行。问题出在翻译这一步。
假设一个登录页面,程序收到你输入的用户名和密码后,拼出一条SQL:
SELECT * FROM users WHERE username = '你输入的用户名' AND password = '你输入的密码' 如果你老老实实输入,数据库就老老实实查。但如果你在用户名框里输入 admin' --,整条语句就变了:
SELECT * FROM users WHERE username = 'admin' --' AND password = '随便什么' 两个连字符在SQL里是注释符,后面的密码验证直接被注释掉了。数据库只看到“查一个叫admin的用户”,密码条件消失。你不需要知道密码,就能以admin身份登录。
这就是SQL注入的核心:用户输入的数据没有被当作纯数据对待,反而被数据库当成了可执行的代码。数据和指令的边界被打破了。
我见过一个真实案例。某小型电商网站的商品详情页URL长这样:product.php?id=10。有人把id改成 10 UNION SELECT username, password FROM users,页面直接把用户表的内容渲染成了商品名称和描述。攻击者甚至不需要写代码,在浏览器地址栏里就能拖库。
更隐蔽的玩法是盲注。数据库不返回错误信息,页面也不显示查询结果,攻击者靠“页面正常”和“页面空白”这种布尔状态,一个字符一个字符地猜数据。猜一个密码可能要发几千次请求,但脚本一跑,几分钟的事。
SQL注入能造成多大破坏,取决于数据库账号的权限。如果网站用的是root连接数据库,攻击者可以读任意表、删任意数据,甚至通过INTO OUTFILE往服务器写文件,进一步提权拿shell。一个输入框没过滤好,整台服务器就没了。
为什么这么多年了还有SQL注入?因为拼接字符串写SQL太顺手了。新手教程这么教,老项目这么写,改起来又麻烦。参数化查询明明能解决问题——把用户输入永远当数据,不参与SQL语句的拼接——但总有人觉得“我转义一下引号就行了”。转义不覆盖所有场景,编码绕过、宽字节注入,花样多得很。
我自己的判断是:只要还有人在用字符串拼接写SQL,SQL注入就不会消失。它不依赖什么高深漏洞,纯粹是开发习惯问题。一个输入框,一个没过滤的参数,就足够了。
防御方法其实不复杂。参数化查询是首选,所有主流语言和数据库驱动都支持。实在不行,用白名单限制输入类型——id只允许数字,用户名只允许字母数字下划线。再退一步,最小权限原则:给网站配一个只能读写的数据库账号,别用root。三层里做到任何一层,攻击成本都会高很多。
下次你在某个网站输入框里手滑打了个单引号,页面报了个数据库错误——那个网站大概率存在SQL注入。别试,直接关掉。你不需要当黑客,但至少得知道,那个小小的输入框背后,可能连着一整个数据库。
