SQL 注入 SQLi

一种针对网站的攻击方式:有人在表单、搜索框或网址里输入数据库命令,网站不加检查就照样执行,结果把本该保护好的客户资料和业务数据泄露出去,或者被随意修改,甚至被整批删除。

别称

定义

什么是 SQL 注入

您经营一家网店。一位访客在搜索框里输入了一串奇怪的内容,按下回车,页面就把所有客户的姓名、电话和订单记录都显示了出来。没有人偷过密码。他只是在错误的地方输入了恰当的文字,剩下的事都由您的网站代劳了。这就是 SQL 注入。

大多数网站把信息存放在数据库里:一个由许多表格组成、井井有条的仓库,有点像一组电子表格。网站要读取或修改这些信息,就要使用一种叫 SQL(结构化查询语言)的语言。它发出的每一个请求都叫一次查询,比如“找出使用这个邮箱的客户”。

当网站把访客输入的内容原封不动地拼进这些查询里时,SQL 注入就发生了。如果访客输入的不是普通文字而是 SQL,数据库分辨不出区别,会把攻击者的命令当成网站自己写的去执行。人们常把它简称为 SQLi。

SQL 注入攻击是怎样进行的

想象一位银行柜员,客户递来什么纸条,他就一字不差地转给金库的工作人员。正常的纸条写着“请告诉我账户余额”。耍花招的纸条写着“请告诉我账户余额,顺便把所有保险箱都打开”。如果柜员从不先看纸条,金库人员就会照做。

在网站上,步骤通常是这样的:

  1. 攻击者先找到一个会把文字发给数据库的地方:登录表单、搜索框、联系表单,或者网址本身,比如结尾是“?id=25”的商品页面。
  2. 他输入一小段 SQL,代替普通文字。一个有名的例子,是在登录表单的密码栏里输入 ' OR '1'='1。
  3. 网站不加检查,就把这段文字接到自己的查询后面。于是查询变成了类似这样的意思:“如果密码正确,或者 1 等于 1,就让这个人进来”。
  4. 1 永远等于 1,所以数据库回答“是”,攻击者不知道任何密码就登录成功了。

有些攻击更隐蔽。在 SQL 盲注中,页面根本不显示数据,攻击者就向数据库提出只能回答是或否的问题,再看页面有什么反应,或者加载要花多长时间。手工做这件事很慢,所以攻击者会用免费的自动化工具替他们完成。

攻击者能借此做什么

一旦数据库听从了攻击者的命令,损失有多大,要看网站的数据库账号被允许做什么。很多时候,这些权限远远超出网站实际需要。攻击者可能会:

  • 读取私密数据,比如客户的姓名、地址、邮箱、订单记录、病历或保存的密码
  • 冒充其他用户登录,包括管理员
  • 修改数据,比如价格、余额或订单状态
  • 删除整张表,甚至整个数据库
  • 在某些环境下,进入服务器本身,并在上面放置有害文件

为什么这关系到您的生意

SQL 注入是最古老的网络攻击之一,而且至今仍然存在。OWASP 是一个开放社区,发布了有名的 Web 应用风险清单 OWASP Top 10,多年来一直把注入列在其中。这种攻击很容易尝试,而很多网站仍然留着某个被遗忘、可以被它利用的表单。

对企业主来说,真正的损失很少是技术层面的。它可能是一份外泄的客户名单,一家按错误价格卖货的网店,一个丢掉整整一周预约的预订系统,或者一封您不得不发给客户、告诉他们数据已经泄露的通知。在许多国家,像 GDPR 这样的数据保护法律也要求您保护个人数据,并在发生泄露时上报。

您网站上的每一个表单,在开发时都考虑过这个风险吗?那些用旧插件匆忙搭起来的网站,或者多年来经过很多人修改的网站,更容易藏着薄弱的地方。

如何保护网站免受 SQL 注入

主要的解决办法大家都知道,而且有效。大部分防护取决于网站是怎样建起来的,所以下面这些问题,很适合拿去问您的开发人员或服务商。

  • 预编译语句。也叫参数化查询。网站把查询和访客的文字分开发送,数据库永远只把这段文字当作普通数据,从不当作命令。这是最主要的防线。像 Laravel 这样的现代框架,只要开发人员使用它自带的数据库工具,默认就会这样做。
  • 输入检查。电话号码栏只应接受数字,日期栏只应接受日期。尽早拒绝奇怪的输入,能堵住很多漏洞。
  • 最小权限。网站用来连接数据库的账号,只应拥有它需要的权限。一个公开的搜索页面,没有任何理由去删除表格。
  • 低调的错误提示。屏幕上详细的数据库报错,等于给攻击者递了一张地图。给访客看简短明了的提示,把详细信息记在内部日志里。
  • 及时更新。平台、插件和代码库都要保持最新,因为旧版本往往存在已知漏洞。
  • Web 应用防火墙。这是放在网站前面的一道过滤器,能在很多已知攻击到达代码之前就把它们挡住。它有帮助,但修不好不安全的代码。
  • 定期测试。渗透测试(由专家进行的安全、有计划的模拟攻击)和漏洞扫描,能赶在攻击者之前找出薄弱环节。

日常做法的对比如下:

有风险的做法更安全的做法
把访客输入直接拼进查询每次查询都使用预编译语句
一个拥有全部权限的数据库账号包办一切网站每个部分各用一个权限受限的账号
在页面上显示完整的数据库报错给访客简短提示,详细信息写进内部日志
插件几个月都不更新定期更新,并清楚列出已安装的内容
只测试功能能不能用也测试有人输入有害内容时会发生什么

常见的误区

  • 只信任浏览器里的检查。在访客自己设备上运行的检查很容易被绕过,所以服务器必须把所有内容再检查一遍。
  • 以为小网站很安全。自动化工具会扫描大量网站,根本不在乎网站大小。
  • 修好一个表单,忘了其他地方。搜索框、筛选条件、网址,以及手机应用背后的 API,都需要同样的重视。
  • 用明文保存密码。一旦数据外泄,用强哈希保存的密码(被转换成无法还原读取的乱码)就很难被滥用。
  • 只依赖防火墙。过滤器能为您争取时间,但它背后那条不安全的查询仍然需要修复。

我们能提供哪些帮助

在 Linkysoft,SQL 注入检测是我们网络安全服务的一部分。我们会对您的网站、应用和 API 进行安全的模拟攻击,审查代码,然后用通俗易懂的语言列出我们发现的问题和修复方法。修复完成后,我们会再测试一次。由其他团队开发的网站同样适用,而免费的安全检查是一个轻松的起点。

正在规划新系统吗?我们的Web 应用和管理系统从设计之初就注重安全,按照 OWASP Top 10 进行加固,并在上线前完成渗透测试。

关于SQL 注入的常见问题

用简单的话说,SQL 注入是什么?
这是一种手段:有人在网站表单或网址里输入数据库命令。如果网站不检查这段文字,数据库就会执行这些命令。攻击者随后就能读取、修改或删除数据。
小网站也会遭到 SQL 注入吗?
会。大多数攻击来自自动化工具,它们随机扫描网站,不管网站大小。任何带有表单、搜索框或后台数据库的网站,都可能成为目标。
怎么知道我的网站有没有 SQL 注入漏洞?
最稳妥的办法,是请懂行的人做一次渗透测试或漏洞扫描。他们会安全地尝试这种攻击,并告诉您哪些页面存在风险。如果页面上出现奇怪的数据库报错,也是一个警告信号。
防止 SQL 注入最好的方法是什么?
每一次数据库查询都使用预编译语句,也叫参数化查询。它把访客输入的文字和命令分开,数据库永远不会去执行这些文字。再加上输入检查、限制数据库权限和定期更新。
防火墙能挡住 SQL 注入吗?
Web 应用防火墙能拦截很多已知的攻击模式,是一层不错的额外保护。但它修不好背后不安全的代码,而且攻击者总在寻找绕过过滤的新办法。代码本身仍然必须安全。
什么是 SQL 盲注?
这是一种页面不显示任何数据库数据的攻击方式。攻击者提出只能回答是或否的问题,观察页面怎么变化,或者需要多久才响应。速度更慢,但依然可能把数据库里的内容摸清楚。
如果我的网站遭到 SQL 注入,该怎么办?
先拦住攻击,或把受影响的部分下线,然后找到并修复有问题的查询。更换密码和密钥,查清哪些数据被读取或修改,需要时从备份中恢复干净的数据。根据您所在地的法律,可能还需要通知客户。
SQL 注入只是网站的问题吗?
不是。手机应用、电脑软件,以及任何把用户输入发送到 SQL 数据库的系统,都可能有同样的弱点。在应用里,风险通常出在 API 上,也就是应用与服务器通信用的连接。

还不确定这与您的项目有什么关系?

告诉我们您正在打造什么,我们将用简单明了的语言为您解答。