SQL 注入 SQLi
一种针对网站的攻击方式:有人在表单、搜索框或网址里输入数据库命令,网站不加检查就照样执行,结果把本该保护好的客户资料和业务数据泄露出去,或者被随意修改,甚至被整批删除。
定义
什么是 SQL 注入
您经营一家网店。一位访客在搜索框里输入了一串奇怪的内容,按下回车,页面就把所有客户的姓名、电话和订单记录都显示了出来。没有人偷过密码。他只是在错误的地方输入了恰当的文字,剩下的事都由您的网站代劳了。这就是 SQL 注入。
大多数网站把信息存放在数据库里:一个由许多表格组成、井井有条的仓库,有点像一组电子表格。网站要读取或修改这些信息,就要使用一种叫 SQL(结构化查询语言)的语言。它发出的每一个请求都叫一次查询,比如“找出使用这个邮箱的客户”。
当网站把访客输入的内容原封不动地拼进这些查询里时,SQL 注入就发生了。如果访客输入的不是普通文字而是 SQL,数据库分辨不出区别,会把攻击者的命令当成网站自己写的去执行。人们常把它简称为 SQLi。
SQL 注入攻击是怎样进行的
想象一位银行柜员,客户递来什么纸条,他就一字不差地转给金库的工作人员。正常的纸条写着“请告诉我账户余额”。耍花招的纸条写着“请告诉我账户余额,顺便把所有保险箱都打开”。如果柜员从不先看纸条,金库人员就会照做。
在网站上,步骤通常是这样的:
- 攻击者先找到一个会把文字发给数据库的地方:登录表单、搜索框、联系表单,或者网址本身,比如结尾是“?id=25”的商品页面。
- 他输入一小段 SQL,代替普通文字。一个有名的例子,是在登录表单的密码栏里输入 ' OR '1'='1。
- 网站不加检查,就把这段文字接到自己的查询后面。于是查询变成了类似这样的意思:“如果密码正确,或者 1 等于 1,就让这个人进来”。
- 1 永远等于 1,所以数据库回答“是”,攻击者不知道任何密码就登录成功了。
有些攻击更隐蔽。在 SQL 盲注中,页面根本不显示数据,攻击者就向数据库提出只能回答是或否的问题,再看页面有什么反应,或者加载要花多长时间。手工做这件事很慢,所以攻击者会用免费的自动化工具替他们完成。
攻击者能借此做什么
一旦数据库听从了攻击者的命令,损失有多大,要看网站的数据库账号被允许做什么。很多时候,这些权限远远超出网站实际需要。攻击者可能会:
- 读取私密数据,比如客户的姓名、地址、邮箱、订单记录、病历或保存的密码
- 冒充其他用户登录,包括管理员
- 修改数据,比如价格、余额或订单状态
- 删除整张表,甚至整个数据库
- 在某些环境下,进入服务器本身,并在上面放置有害文件
为什么这关系到您的生意
SQL 注入是最古老的网络攻击之一,而且至今仍然存在。OWASP 是一个开放社区,发布了有名的 Web 应用风险清单 OWASP Top 10,多年来一直把注入列在其中。这种攻击很容易尝试,而很多网站仍然留着某个被遗忘、可以被它利用的表单。
对企业主来说,真正的损失很少是技术层面的。它可能是一份外泄的客户名单,一家按错误价格卖货的网店,一个丢掉整整一周预约的预订系统,或者一封您不得不发给客户、告诉他们数据已经泄露的通知。在许多国家,像 GDPR 这样的数据保护法律也要求您保护个人数据,并在发生泄露时上报。
您网站上的每一个表单,在开发时都考虑过这个风险吗?那些用旧插件匆忙搭起来的网站,或者多年来经过很多人修改的网站,更容易藏着薄弱的地方。
如何保护网站免受 SQL 注入
主要的解决办法大家都知道,而且有效。大部分防护取决于网站是怎样建起来的,所以下面这些问题,很适合拿去问您的开发人员或服务商。
- 预编译语句。也叫参数化查询。网站把查询和访客的文字分开发送,数据库永远只把这段文字当作普通数据,从不当作命令。这是最主要的防线。像 Laravel 这样的现代框架,只要开发人员使用它自带的数据库工具,默认就会这样做。
- 输入检查。电话号码栏只应接受数字,日期栏只应接受日期。尽早拒绝奇怪的输入,能堵住很多漏洞。
- 最小权限。网站用来连接数据库的账号,只应拥有它需要的权限。一个公开的搜索页面,没有任何理由去删除表格。
- 低调的错误提示。屏幕上详细的数据库报错,等于给攻击者递了一张地图。给访客看简短明了的提示,把详细信息记在内部日志里。
- 及时更新。平台、插件和代码库都要保持最新,因为旧版本往往存在已知漏洞。
- Web 应用防火墙。这是放在网站前面的一道过滤器,能在很多已知攻击到达代码之前就把它们挡住。它有帮助,但修不好不安全的代码。
- 定期测试。渗透测试(由专家进行的安全、有计划的模拟攻击)和漏洞扫描,能赶在攻击者之前找出薄弱环节。
日常做法的对比如下:
| 有风险的做法 | 更安全的做法 |
|---|---|
| 把访客输入直接拼进查询 | 每次查询都使用预编译语句 |
| 一个拥有全部权限的数据库账号包办一切 | 网站每个部分各用一个权限受限的账号 |
| 在页面上显示完整的数据库报错 | 给访客简短提示,详细信息写进内部日志 |
| 插件几个月都不更新 | 定期更新,并清楚列出已安装的内容 |
| 只测试功能能不能用 | 也测试有人输入有害内容时会发生什么 |
常见的误区
- 只信任浏览器里的检查。在访客自己设备上运行的检查很容易被绕过,所以服务器必须把所有内容再检查一遍。
- 以为小网站很安全。自动化工具会扫描大量网站,根本不在乎网站大小。
- 修好一个表单,忘了其他地方。搜索框、筛选条件、网址,以及手机应用背后的 API,都需要同样的重视。
- 用明文保存密码。一旦数据外泄,用强哈希保存的密码(被转换成无法还原读取的乱码)就很难被滥用。
- 只依赖防火墙。过滤器能为您争取时间,但它背后那条不安全的查询仍然需要修复。
我们能提供哪些帮助
在 Linkysoft,SQL 注入检测是我们网络安全服务的一部分。我们会对您的网站、应用和 API 进行安全的模拟攻击,审查代码,然后用通俗易懂的语言列出我们发现的问题和修复方法。修复完成后,我们会再测试一次。由其他团队开发的网站同样适用,而免费的安全检查是一个轻松的起点。
正在规划新系统吗?我们的Web 应用和管理系统从设计之初就注重安全,按照 OWASP Top 10 进行加固,并在上线前完成渗透测试。