如何保证SQL Server免遭SQL注入攻击?

日期: 2008-07-08 作者:Denny Cherry翻译:Shirley Xie 来源:TechTarget中国 英文

SQL注入攻击可能是黑客攻击面向互联网的SQL Server数据库最常用的方式。任何使用动态SQL、允许未经检验的用户输入提交到数据库的应用程序都面临SQL注入攻击的风险,无论你的网络有多安全,或者你安装了多少防火墙。最近有一项关于Web黑客攻击的报告显示,SQL注入攻击呈上升趋势,不仅仅导致数据盗窃和数据丢失,而且在最近一连串的自动注入攻击中,数据库被破坏,向用户提供恶意Java脚本。这种渗透导致Web服务器令客户端电脑感染上其它的病毒。

报告对于已经遭到攻击的网站数量统计不一,不过,哪怕是最低的数字都上万。在感染的高峰期,甚至联合国的网站也无法幸免。   你可能会认为SQL Server平台……

我们一直都在努力坚持原创.......请不要一声不吭,就悄悄拿走。

我原创,你原创,我们的内容世界才会更加精彩!

【所有原创内容版权均属TechTarget,欢迎大家转发分享。但未经授权,严禁任何媒体(平面媒体、网络媒体、自媒体等)以及微信公众号复制、转载、摘编或以其他方式进行使用。】

微信公众号

TechTarget微信公众号二维码

TechTarget

官方微博

TechTarget中国官方微博二维码

TechTarget中国

电子邮件地址不会被公开。 必填项已用*标注

敬请读者发表评论,本站保留删除与本文无关和不雅评论的权力。

SQL注入攻击可能是黑客攻击面向互联网的SQL Server数据库最常用的方式。任何使用动态SQL、允许未经检验的用户输入提交到数据库的应用程序都面临SQL注入攻击的风险,无论你的网络有多安全,或者你安装了多少防火墙。最近有一项关于Web黑客攻击的报告显示,SQL注入攻击呈上升趋势,不仅仅导致数据盗窃和数据丢失,而且在最近一连串的自动注入攻击中,数据库被破坏,向用户提供恶意Java脚本。这种渗透导致Web服务器令客户端电脑感染上其它的病毒。报告对于已经遭到攻击的网站数量统计不一,不过,哪怕是最低的数字都上万。在感染的高峰期,甚至联合国的网站也无法幸免。

  你可能会认为SQL Server平台既然这么不安全,不如考虑更换平台。但事实上,所有的数据库平台都受到这种攻击的困扰。由于在主机环境中更多部署的是SQL Server,所以,针对SQL Server的攻击也就相应更为普遍。开发人员进行网页开发工作,他们不知道如何防范这样的攻击。由于这种攻击的成功率很高,所以,在恶意软件的社区内颇为流行。

  SQL注入攻击是如何工作的?

  容易遭受SQL注入攻击的Web应用程序具有以下特点:

  1.你的网站使用动态SQL。这不是指应用程序动态生成select或者insert语句。它是指任何代码是动态生成的,包括应用程序在执行语句之前,动态生成一个存储过程。

  2.当从客户端应用程序取值的时候,这些值没有经过验证——也可能没有对语法或者转义符进行验证。

  SQL注入攻击是这样进行的:攻击者修改现有命令行,通过在字符串值内插入一个单引号,或者在数字后面添加分号,在转义符后面写入SQL语句。命令行看上去类似这样:

exec sel_CustomerData @CustomerId=47663; truncate TABLE Customer

  这样会执行sel_CustomerData过程,然后运行truncate TABLE命令,删除Customer数据表的内容。如果有Foreign Key约束这个数据表,数据库将会返回错误,向黑客提供受约束的数据表名称。一名聪明的黑客可以利用这个技巧,查找到数据库里面每一个表的名称。然后,黑客能够将数据插入你的数据库,或者从你的表中选择数据(取决于数据库给了应用程序什么样的权限)。当黑客获取了数据表中的数据,就可以使用xp_sendmail或sp_send_dbmail向他们自己发送电子邮件。即使你已经禁用这些过程,黑客可以轻易启用这些过程,或者使用sp_OA过程添加他们自己的过程。

  如何确保SQL Server数据的安全,避免SQL注入?

  有多种办法可以保护你的数据库,避免这样的攻击。

  首先,我们需要采用数据库安全的最佳实践方法加固数据库安全。这包括将数据库的操作许可设置为最低级别(setting up the database security with the lowest set of permissions possible.)。同时,应用程序不要直接访问数据表。所有对数据表的访问应该通过存储过程进行,而且那些存储过程不应该包括任何动态SQL。

  避免对表的直接访问,你可以很大地减少受攻击的层面。但是,这并不是唯一必须做的事情。存储过程也存在受到攻击的可能性。虽然对存储过程进行攻击需要花费更多的时间,但是,仍然有可能利用你的存储过程对数据库进行破坏。存储过程就是用来向数据库中插入、更新和删除数据。一个聪明的黑客可以利用你自己的存储过程攻击你。

  这是需要应用开发人员和你共同工作的方面,以确保被执行的代码(the code being executed against the database)是安全的。如果不确保应用层的安全,防范SQL注入攻击,其他的工作都将是徒劳的。数据只要进入数据库,基本上不可能在数据库内进行验证。这需要在应用层对数据进行验证。

  应用程序与数据库最简单配合使用的方法就是在应用程序内动态生成SQL命令。下面的示例中,.NET代码从前台应用程序中调用(populate)v_Input变量:
  …
  Dim v_Conn As New SqlConnection(p_Connectionstring)
  v_Conn.Open()
  Dim v_cmd As New SqlCommand
  v_cmd.Connection = v_Conn
  v_cmd.CommandType = CommandType.Text
  v_cmd.CommandText = "exec sel_CustomerData @CustomerName=’" & v_Input & "’"
  Dim v_DR As SqlDataReader
  v_DR = v_cmd.executeReader
  v_DR.Close()
  v_DR = Nothing
  v_cmd.Dispose()
  v_cmd = Nothing
  v_Conn.Close()
  v_Conn = Nothing
  v_DR.Close()

  如果你不在v_Input变量中对数据进行验证,就相当于为SQL注入攻击敞开大门。如果你对输入不进行验证,就会允许攻击者传入一个单引号和一个分号,这样,将告诉SQL Server结束当前的语句,转而执行另一段sql语句pass in a single quote, and a semicolon, which tells the SQL Server to end the value and the statement moving on to the next statement in the batch。例如像这样的值“Smith ’; truncate table Customer; declare @myV =”。通过SQL Server执行的SQL语句会变成:The resulting SQL statement executed against the SQL Server
exec sel_CustomerData @CustomerName=’Smith’; truncate table Customer; declare @myV = ’’

  当应用程序(calling application runs the code)运行这段代码的时候,将运行存储过程,然后表被清空。你需要进行一些基本的验证,将变量中的任何单引号替换为两个单引号。这样,就可以中止SQL Server运行删除语句truncated statement,因为现在它是值的一部分。通过这样的简单变化,我们的数据库调用现在就会像这样:

  exec sel_CustomerData @CustomerName=’Smith’’; truncate table Customer; declare @myV = ’’’

  一种更好更安全的解决方式就是把存储过程代码用参数来表示。这让.NET来处理变量的数据净化,这样,任何注入代码都不会执行。

  .NET代码从你的前台应用程序中调用v_Input变量。

  …
  Dim v_Conn As New SqlConnection(p_Connectionstring)
  v_Conn.Open()
  Dim v_cmd As New SqlCommand
  Dim v_Parm As New SqlParameter
  v_cmd.Connection = v_Conn
  v_cmd.CommandType = CommandType.StoredProcedure
  v_cmd.Parameters.Add("@CustomerName", SqlDbType.NVarchar, 255)
  v_cmd.Parameters.Item("@CustomerName").Direction = ParameterDirection.Input
  v_cmd.Parameters.Item("@CustomerName").Value = v_Input
  v_cmd.CommandText = "sel_CustomerData"
  Dim v_DR As SqlDataReader
  v_DR = v_cmd.executeReader
  v_DR.Close()
  v_DR = Nothing
  v_cmd.Dispose()
  v_cmd = Nothing
  v_Conn.Close()
  v_Conn = Nothing
  v_DR.Close()

  如果网站的前台应用程序和后台数据库的安全无法正确得到全面的保障,你的系统和数据就很容易受到SQL注入攻击。这些攻击可能表面看上去没有造成什么影响,但如果把你的所有客户数据暴漏给攻击者,问题就大了。破坏程度可以导致所有的数据被删除,或者你的网站和应用程度被用来向客户发送病毒。短期而言,这会让客户的电脑受到感染。长远来看,你的公司可能会列入不安全站点名单。

  注:本文中的.NET代码仅作参考之用,未经测试,或保证可行。我是一名DBA,不是一名.NET开发人员,所以,提供此代码时为了介绍基本的概念,而不是作为生产的用途。

  作者简介:Denny Cherry具有十多年管理SQL Server的经验,包括MySpace.com网站近两亿用户的安装。Denny的专长领域包括系统架构、性能调优、复制和疑难解答。他是Awareness科技公司的高级数据库管理员和架构师。Denny是SQL Server专业协会(PASS)以及SQL Server专家Quest Software协会的终身会员,在SQL Server管理方面发表了无数技术文章。

相关推荐