【SQL注入攻击】认识注入攻击与7种防范方式
SQL为结构化查询语言(Structured Query Language)的缩写,是一种可以管理数据库的编程语言,用来对数据库进行查询、插入、删除数据,以及更新数据库等操作。使用SQL的数据库应用广泛,因此针对SQL的SQL注入(SQL Injection)攻击长期以来被致力于信息安全的国际非营利组织OWASP(Open Web Application Security Project)列在十大网络攻击名单中。那么,究竟什么是SQL注入?它的运作原理是什么?可以造成哪些威胁?又该如何防范?本文将以深入浅出的方式回答以上问题。
认识 SQL injection(SQL 注入)
SQL注入攻击常被翻译作SQL注入、插入、注射、注码或数据隐码攻击,顾名思义是以SQL编程语言进行的注入攻击(Injection Attacks),利用网页/应用程序与数据库之间的安全漏洞,窃取或破坏数据。
所谓的注入攻击指的是,黑客通过输入代码至网页或应用程序中,在其执行过程中或目的上动手脚,使系统误将恶意代码当成合法指令并执行。用比喻的方式来说,注入攻击可以想象成:法庭上,被告在姓名栏位填入自己的名字某某以及「无罪」两字。法官在读取被告个人资料时,便会直接念出「某某无罪」。
一、SQL injection 攻击原理
SQL注入可能会因个别数据库设置不同而有所变化,但其核心概念皆为:黑客在提供用户输入信息的字段中,键入SQL语法。例如在登录栏位、搜索栏位、联系表单等位置,以SQL代码对数据库下达指令。
【各欄位示意圖】
以下比较正常SQL指令和SQL注入攻击,并以实际例子说明SQL注入。
假设用户输入正确的账号(AAA)及密码(12345)后,数据库收到的SQL指令为:
Select user_data from TABLE Where user_name=‘AAA’ and password=‘12345’ |
代表从数据库中的「TABLE」表格中,执行以下:
取出用户数据: 满足(用户名等于AAA)TRUE 并且 AND 满足(用户密码等于12345)TRUE |
用户名等于AAA为「条件1」,而用户密码为12345为「条件2」。程序在数据库中找到用户名AAA并且密码为12345的用户后,程序便会判断「条件1」和「条件2」皆为TRUE,并提取该用户数据。
黑客在不知道正确账号密码的情况下,也可以通过在账号密码栏位下输入SQL指令登录系统。例如在账号密码栏位输入空白以及「OR 1=1」:
Select user_data from TABLE Where user_name=‘ OR 1=1’ and password=‘ OR 1=1’ |
代表从数据库中的「TABLE」表格中,执行以下:
取出用户数据: 满足(用户名等于 或 1=1)FALSE OR TRUE 并且 AND 满足(用户密码等于 或 1=1)FALSE OR TRUE |
在这个范例里,条件1为「『空白内容』或是『1=1』」,系统无法找到空白内容的用户名,但「1=1」为TRUE,因此条件1仍会被判定为TRUE。同样道理,条件2也会被判定为TRUE。黑客便可以顺利登录系统,获取数据。
【SQL injection 攻擊流程示意圖】
SQL injection 攻击会造成什么影响?
黑客可利用SQL注入攻击干扰应用程序,取得未经授权的数据、篡改数据库中的数据、颠覆应用程序逻辑等,进而威胁到对无论是个人、组织还是公司企业来说,最有价值的数据。数据遭窃的个人用户,可能遭盗用身份、盗刷信用卡或因此陷入钓鱼诈骗的陷阱;对企业组织来说亦是非同小可,可能导致公司名誉受损、客户流失、法律纠纷、金钱损失等危机。
除此之外,SQL注入还可以衍生和搭配不同网络攻击手法,达到不同的攻击目的。例如黑客甚至能通过SQL注入,攻击应用程序的服务器或其他后端基础架构;借着SQL注入发动拒绝服务(DoS)攻击;或发动复合SQL注入攻击,针对同一目标同时使用DDoS攻击或其他网络攻击。
【想要進一步瞭解 Dos 攻击和 DDoS 攻击嗎?請參考《DDoS 攻击》文章。】
SQL 注入攻击的种类
SQL注入攻击本身原理虽然单纯,但实际使用上,会根据各数据库查询规定设置差异,出现各种情况。同时,网页和应用程序开发者不断加强数据库防御,黑客也会想更多办法绕过预防措施。而依据黑客存取后端数据的方式,以及可造成的影响,SQL注入可以分成三大类:In-band SQL Injection、Inferential SQL Injection和Out-of-band SQL Injection。
一、In-band SQL injection
In-band SQL Injection也称作“经典SQL注入”,指黑客利用同一个沟通管道(即用户和应用程序互动的界面)发动SQL注入攻击和收集窃取来的信息。例如黑客在同一网页上入侵数据库和提取数据。In-band SQL Injection是最简单的攻击方式,也因此最为普遍,又有Error-based和Union-based两种子类别。
Error-based故意以错误的SQL查询来获得关于数据库本身结构的信息,用以策划未来、针对性更高的网络攻击。而Union-based则是利用Union运算子(SQL Union Operator)将两个或两个以上的SQL查询合并在一起,在单一字段中,要求数据库提供其他多项信息。
二、Inferential SQL injection/Blind SQL injection
有些网站页面不会在发生错误时,提供错误的详细内容或其他数据库信息。但黑客可借由反复盲测、和数据库互动,并观察其反应,进一步了解攻击目标,这样的攻击手法称为Inferential SQL Injection或Blind SQL Injection。黑客使用这类SQL注入攻击,所花费时间较多,但具有一定威胁性。Blind SQL Injection同样可以分成两个子类别:Boolean-based和Time-based。
Boolean-based类型的SQL注入中,黑客对数据库送出SQL查询后,观察服务器的回应来判断该查询的条件是否为真。另一方面,黑客则依据服务器回应所需的时间,推断送给数据库的查询内容是否为真。
三、Out-of-band SQL injection
相对于In-band SQL Injection,进行Out-of-band SQL Injection时,黑客使用不同的沟通管道攻击和收集数据。由于Out-of-band SQL Injection主要针对与数据库连接的其他系统,如DNS服务器等,受攻击的目标服务器需要有其他连接,并且能够以DNS或HTTP回应,攻击才能顺利发挥效用。因此Out-of-band SQL Injection有一定限制,而较少为黑客所用。
7 种 SQL injection 防范方式
提供网站或应用程序服务的企业,在实践中可以通过以下方式阻断SQL注入攻击:
-
将查询参数化(Query Parameterization):开发人员可以事先定义所有SQL代码为不同的参数,并限制使用参数进行SQL查询。如此一来,可输入查询的内容范围有限,黑客便无法任意使用SQL代码,要求服务器执行指令。
-
转义参数(Escape Parameters):检查输入的查询内容,并将其中夹杂的SQL代码替换成其他字符,以防止SQL代码被置入网页或应用程序。但采用此方法需多留意SQL语法更新,随其修改检查规定;同时检查规则中可能有遗漏的SQL代码,降低防范强度。
-
使用白名单(White List):建立白名单,只允许特定的数值输入进字段。
-
采用最低权限原则(Principle of Least Privilege,PoLP):将SQL指令限制在最小的范围里,通过降低SQL指令可以执行的动作,减少SQL注入攻击的风险。
-
不显示错误信息:针对Blind SQL Injection,可减少透露错误的原因,仅显示“请重新再试一次”,避免黑客借盲测收集情报。
-
关闭预设账号:有些数据库会有预设的账号,未关闭或移除预设账号,给黑客有机可乘,透过SQL注入登录。
-
注意数据表命名方式:使用SQL注入攻击时,黑客需猜测数据库中的数据表和字段名称。例如“以SQL指令要求应用程序从数据库中的某一表格删除数据”。若使用“login”或“user”等常见名称命名表格,黑客猜中的概率较高,SQL注入攻击的成功概率也因此提高。
现代社会中,数据的重要性不可言喻。针对数据而进行的SQL注入攻击固然可怕,但只要采取适当的防御措施,谨慎制定数据库查询规则,就可以将风险降至最低。