SQL注入

代碼注入軟件漏洞的類型

SQL注入(英语:SQL injection),也称SQL隐码SQL注码,是发生于应用程式与资料库层的安全漏洞。简而言之,是在输入的字串之中夹带SQL指令,在设计不良的程式当中忽略了字元检查,那么这些夹带进去的恶意指令就会被资料库伺服器误认为是正常的SQL指令而执行,因此遭到破坏或是入侵。[2]

“SQL注入”的各地常用名称
中国大陆SQL注入
台湾SQL注入、SQL隐码、SQL注码[1]

有部份人认为SQL注入是只针对Microsoft SQL Server,但只要是支援处理SQL指令的资料库伺服器,都有可能受到此种手法的攻击。

原因

 
Xkcd上的一幅漫画。该学生的姓名为“Robert'); DROP TABLE students;--”,导致students表被删除。[3]

在应用程式中若有下列状况,则可能应用程式正暴露在SQL Injection的高风险情况下:

  1. 在应用程式中使用字串联结方式或联合查询方式组合SQL指令。
  2. 在应用程式连结资料库时使用权限过大的帐户(例如很多开发人员都喜欢用最高权限的系统管理员帐户(如常见的root,sa等)连接资料库)。
  3. 在资料库中开放了不必要但权力过大的功能(例如在Microsoft SQL Server资料库中的xp_cmdshell延伸预存程序或是OLE Automation预存程序等)
  4. 太过于信任使用者所输入的资料,未限制输入的特殊字元,以及未对使用者输入的资料做潜在指令的检查。

作用原理

  1. SQL命令可查询、插入、更新、删除等,命令的串接。而以分号字元为不同命令的区别。(原本的作用是用于SubQuery或作为查询、插入、更新、删除……等的条件式)
  2. SQL命令对于传入的字串参数是用单引号字元所包起来。(但连续2个单引号字元,在SQL资料库中,则视为字串中的一个单引号字元)
  3. SQL命令中,可以夹带注解(连续2个减号字元 -- 后的文字为注解,或“/*”与“*/”所包起来的文字为注解)
  4. 因此,如果在组合SQL的命令字串时,未针对单引号字元作跳脱处理的话,将导致该字元变数在填入命令字串时,被恶意窜改原本的SQL语法的作用。

例子

某个网站的登入验证的SQL查询代码为

strSQL = "SELECT * FROM users WHERE (name = '" + userName + "') and (pw = '"+ passWord +"');"

恶意填入

userName = "1' OR '1'='1";

passWord = "1' OR '1'='1";

时,将导致原本的SQL字串被填为

strSQL = "SELECT * FROM users WHERE (name = '1' OR '1'='1') and (pw = '1' OR '1'='1');"

也就是实际上运行的SQL命令会变成下面这样的

strSQL = "SELECT * FROM users;"

因此达到无帐号密码,亦可登入网站。所以SQL注入被俗称为骇客的填空游戏。

可能造成的伤害

  1. 资料表中的资料外泄,例如企业及个人机密资料,帐户资料,密码等。
  2. 资料结构被骇客探知,得以做进一步攻击(例如SELECT * FROM sys.tables)。
  3. 资料库伺服器被攻击,系统管理员帐户被窜改(例如ALTER LOGIN sa WITH PASSWORD='xxxxxx')。
  4. 取得系统较高权限后,有可能得以在网页加入恶意连结、恶意代码以及Phishing等。
  5. 经由资料库伺服器提供的作业系统支援,让骇客得以修改或控制作业系统(例如xp_cmdshell "net stop iisadmin"可停止伺服器的IIS服务)。
  6. 攻击者利用数据库提供的各种功能操纵文件系统,写入Webshell,最终导致攻击者攻陷系统
  7. 破坏硬碟资料,瘫痪全系统(例如xp_cmdshell "FORMAT C:")。
  8. 取得系统最高权限后,可针对企业内部的任一管理系统做大规模破坏,甚至让其企业倒闭。
  9. 网站首页被窜改,导致声誉受到损害。

避免的方法

  1. 在设计应用程式时,完全使用参数化查询(Parameterized Query)来设计资料存取功能。
  2. 在组合SQL字串时,先针对所传入的参数加入其他字元(将单引号字元前加上跳脱字元)。
  3. 如果使用PHP开发网页程式的话,需加入跳脱字元之功能(自动将所有的网页传入参数,将单引号字元前加上跳脱字元)。
  4. 使用php开发,可写入html特殊函式,可正确阻挡XSS攻击。
  5. 其他,使用其他更安全的方式连接SQL资料库。例如已修正过SQL注入问题的资料库连接元件,例如ASP.NET的SqlDataSource物件或是 LINQ to SQL。
  6. 增强网页应用程式防火墙的防御力

历史

有关SQL注入的首次公开讨论始于1998年左右。[4]例如,Phrack Magazine英语Phrack Magazine中的1998年文章。[5]

参考文献

  1. ^ 国家教育研究院双语词汇、学术名词暨辞书资讯网
  2. ^ Microsoft. SQL Injection. [2013-08-04]. (原始内容存档于2013-08-02). SQL injection is an attack in which malicious code is inserted into strings that are later passed to an instance of SQL Server for parsing and execution. Any procedure that constructs SQL statements should be reviewed for injection vulnerabilities because SQLi Server will execute all syntactically valid queries that it receives. Even parameterized data can be manipulated by a skilled and determined attacker. 
  3. ^ 存档副本. [2016-12-16]. (原始内容存档于2016-12-17). 
  4. ^ Sean Michael Kerner. How Was SQL Injection Discovered? The researcher once known as Rain Forrest Puppy explains how he discovered the first SQL injection more than 15 years ago.. November 25, 2013 [2020-05-29]. (原始内容存档于2014-03-18). 
  5. ^ Jeff Forristal (signing as rain.forest.puppy). NT Web Technology Vulnerabilities. Phrack Magazine英语Phrack Magazine. Dec 25, 1998, 8 (54 (article 8)) [2020-05-29]. (原始内容存档于2014-03-19). 

外部链接