SQL注入原理及防范方法

  • 格式:pdf
  • 大小:1.35 MB
  • 文档页数:2

• 178•WEB 技术的发展和普及无疑方便了人们的生活,目前,大量的互联网服务都可以通过WEB 直接获取,从而不再需要下载各种各样的客户端。

WEB 技术的发展虽然方便了人们的生活但也可能会带来个人信息泄露的安全隐患。

目前针对WEB 应用的攻击手段层出不穷,在WEB 应用如此广泛的今天,一旦开发者在网站的设计过程中没有注意防范相应的攻击,由攻击造成的危害将可能是灾难性的。

本文主要介绍WEB 攻击中的SQL 注入攻击并在将在最后给出此类攻击的预防手段。

一、一阶SQL注入原理S Q L 注入攻击就是将S Q L 命令或SQL 关键字插入到WEB 表单,用以构造恶意的SQL 语句,并以此欺骗WEB 服务器执行此恶意的SQL 语句进行相关的数据库操作,从而实现对网站后台数据库的非法访问或实施非授权修改。

一阶SQL 注入攻击是指攻击行为发生在一个HTTP 请求和响应中,其对于系统的攻击往往是立即执行的。

以网站中常见的用户登录功能为例,阐述一阶SQL 注入的原理:用户在进行登录时需要利用WEB 表单向后台提交自己的用户名和密码,以便后台相应的处理程序在数据库中查询是否有与之对应的记录,以此来验证用户身份。

后台执行查询的SQL 语句通常可表示为:SELECT * FROM user_table WHERE username = ‘username ’AND password =‘user_password ’在后台提交查询请求到DBMS 进行数据库查询操作前,根据用户在网站前端的输入构造SQL 语句的一般方式为:String sql=“SELECT * FROM user_table WHERE username =‘” + user-name_string +“’AND password =‘”+ password_string +“’”其中username_string 是保存了用户输入用户名的String 类型变量,pas-sword_string 是保存了用户输入密码的String 类型变量。

根据前端用户输入构造相应的查询语句后,网站后台相应的处理模块便将保存了数据库查询语句的String 型变量sql 通过相应的数据库访问函数提交到DBMS 进行查询。

相应的查询语句用于在数据库中寻找满足WHERE 条件的记录并返回相应的查询结果。

现假设数据库中存在如下用户记录:用户名:admin ,密码:123456。

账户的合法拥有者通过表单向后台提交自己的用户名admin ,以及密码123456,后台根据用户提交的信息将构造如下查询语句:SELECT * FROM user_table WHERE username =‘ad-min ’ AND password = ‘123456’由于数据库中存在满足WHERE 条件的记录,因此将返回用户名为admin ,密码为123456的用户记录,身份验证通过,用户可以顺利登录并进行相应权限的操作。

假设恶意的攻击者知道上述用户的用户名,并且发现登录界面存在一个SQL 注入点,每个用户的用户名又是唯一的,则他可以通过表单提交以下信息实现非法登录,用户名:admin ,密码:1’OR username =‘admin上述内容被提交到网站后台,后台根据所提交内容将构造出如下查询语句:SELECT * FROM user_table WHERE username =‘ad-min ’ AND password =‘1’OR username =‘admin ’后台用构造出的SQL 语句在查找符合WHERE 条件的记录时,由于AND 运算的优先级高于OR 运算的优先级,所以只要满足username =‘admin ’AND password =‘1’或username =‘admin ’条件之一即可搜索出对应用户名的唯一记录从而实现登录。

尽管攻击者无法得到用户名为admin 的密码,使得第一个条件成立,但是由于他可以相对容易的知道某一用户的用户名,构造原本不在设计之中的第二个条件,使得攻击者可以利用SQL 注入绕过身份验证,实现“无密登录”。

二、二阶SQL注入原理二阶SQL 注入相对于一阶SQL 注入来说,其注入过程更加复杂,也更难以预防。

之所以称其为二阶SQL 注入是因为它的攻击过程分为两次进行,注入攻击发生在两个HTTP 请求中。

现以网站中常见的用户注册和修改密码功能为例说明其原理。

在第一个HTTP 请求中,攻击者构造一个特殊的用户名如“admin ’--”,并利用此用户名通过网站前端的注册用户功能向后台提出注册新用户的请求。

本次操作如果忽略这个精心构造的用户名可视为一次完全合法的操作。

在第二个HTTP 请求中,攻击者通过网站前端的修改密码功能向后台发出修改密码的请求并提交需要修改密码的用户名、原始密码和新密码。

一般的,修改密码即是对数据库现有内容进行更新操作,更新所用的SQL 语句通常可以表示如下:U P D AT E u s e r _t a b l e S E T p a s s w o r d =‘n e w _password ’WHERE username = ‘username ’SQL注入原理及防范方法青岛理工大学刘彦鑫• 179•其中username是用户名,new_password是用户设置的新密码。

攻击者将先前注册的用户名、旧密码以及所要设置的新密码从前端提交到后台,后台在执行修改密码前将先验证用户是否存在以及原密码是否正确,这一步为了安全性往往会将用户的输入进行转义后再执行查询。

检查通过后才构造SQL语句进行数据更新操作:UPDA TE user_table SET password =‘new_password’WHERE username =‘admin’--’值得注意的是,这一步中参数username的值并不是来自用户输入,而是直接来自数据库,所以并没有经过转义处理。

而用户名中的“--”在SQL语法中起注释符的作用,注释符后的语句不会被当做SQL语句参与执行,所以上述语句在执行时真正起作用的部分如下:UPDA TE user_table SET password =‘new_password’WHERE username =‘admin’可以看出,这个语句修改的并不是“admin’--”用户的密码,而是“admin”用户的密码。

这个过程中攻击者利用二阶SQL注入实现了注册新用户对已有用户的密码进行修改,盗取他人账号的目的。

而对于经验丰富的攻击者来说,二阶SQL注入攻击的作用也不仅限于此。

三、SQL注入的防范措施不论是一阶SQL注入攻击还是二阶SQL注入攻击,其原理均是通过网站前端提交具有迷惑性的数据,最终欺骗网站后台构造非法的SQL语句并执行。

在知道了其运作的原理后,相应的就可提出一些措施对其进行防范,从而减少因SQL注入攻击带来的损失。

(一)对可能造成二阶SQL注入攻击的字符采取过滤对用户输入的字符进行转义虽然可以有效防范一阶SQL 注入攻击,但难以防御二阶SQL注入攻击。

但是如果对用户输入的数据实施严格的过滤而非简单的转义,则可以达到较好的防御效果。

过滤相对于转义来说对用户输入数据的要求更加严格,任何可能造成注入攻击的字符一律限制禁止使用。

一旦将用户输入的内容进行严格的控制,便可有效预防SQL注入攻击。

但这样无疑对用户增加了更多的限制,降低了用户的使用体验。

(二)对用户输入的数据采用二进制形式存储SQL注入攻击能够成功的原因之一是因为从数据库中取出的数据以及用户输入的数据均是字符型数据,这些字符型数据与SQL语句混合在一起且没有明确的界限,从而使DBMS在执行相应SQL语句时误将数据中的部分字符作为SQL关键字执行,改变了预期SQL语句的执行逻辑。

如果将存入数据库中的数据以及进行查询时用户输入的数据统一使用二进制数据表示,则DBMS在执行SQL语句时就能明确的区分SQL关键字和数据,SQL注入就难以发生。

当前WEB开发语言(如PHP)均有md5()等能将任意形式的字符串转换为二进制数据的库函数,此方法实现起来相对简单。

但由于二进制数据存在难以阅读的特性,数据库中采用存储二进制数据的方法将使得数据库的维护工作变的困难。

(三)借助于数据类型转换实现安全的数据库操作在数据库中存放二进制数据不利于数据库的维护,存放字符型数据又可能导致二阶SQL注入的发生。

但仍有行之有效的方法可以兼顾数据库的维护和安全性两个方面:将用户在网站前端输入的数据进行编码(如进行二进制编码),利用编码后的数据构造对数据库执行操作的SQL语句,并在SQL语句执行前先将数据库中记录的有关属性值(字符型数据)进行同样的编码,在检查一条记录时通过比较两个编码序列是否相等来判断该条记录是否满足SQL语句的条件。

这种方式在执行SQL语句检查每一条记录时,都使用经过编码的数据进行比对,即使数据部分存在SQL关键字,在经过编码转换后也不会影响SQL语句的执行逻辑,从而防止了一阶SQL注入及二阶SQL注入的发生。

又因为其编码过程是在一条记录需要被检查时才进行的,保证了数据库中可以存放字符型数据,增加了数据库的可维护性。

该方法可使用数据库内置的类型转换函数实现,也可以由用户编写特定的程序模块或存储过程以实现更加多样化的需求。

以SQLServer数据库为例,将上述发生SQL注入的代码进行如下修改:SELECT * FROM user_table WHERE CAST(username AS varbinary(1000)) = CAST(user_input_username AS varbinary(1000)) AND CAST(password AS varbinary(1000)) = CAST(user_input_password AS varbinary(1000))或者:SELECT * FROM user_table WHERE CONVERT(varbinary(1000),usernam e) = CONVERT(varbinary(1000),user_input_username) AND CONVERT(varbina ry(1000),password) = CONVERT(varbinary(1000),user_input_password)其中,CAST()函数和CONVERT()函数是SQLServer中用于对数据类型进行转换的函数,这两个函数均可将字符型数据转换成二进制类型数据,从而实现安全的数据库操作。

总结:本文对SQL注入攻击中较为常见的一阶SQL注入攻击和二阶SQL注入攻击的原理进行了阐述,并且结合案例分析了SQL注入攻击发生的过程。