避免SQL注入

什么是SQL注入

SQL注入攻击(SQL Injection),简称注入攻击,是Web开发中最常见的一种安全漏洞。可以用它来从数据库获取敏感信息,或者利用数据库的特性执行添加用户,导出文件等一系列恶意操作,甚至有可能获取数据库乃至系统用户最高权限。

而造成SQL注入的原因是因为程序没有有效过滤用户的输入,使攻击者成功的向服务器提交恶意的SQL查询代码,程序在接收后错误的将攻击者的输入作为查询语句的一部分执行,导致原始的查询逻辑被改变,额外的执行了攻击者精心构造的恶意代码。

SQL注入实例

很多Web开发者没有意识到SQL查询是可以被篡改的,从而把SQL查询当作可信任的命令。殊不知,SQL查询是可以绕开访问控制,从而绕过身份验证和权限检查的。更有甚者,有可能通过SQL查询去运行主机系统级的命令。

下面将通过一些真实的例子来详细讲解SQL注入的方式。

考虑以下简单的登录表单:

<form action="/login" method="POST">
<p>Username: <input type="text" name="username" /></p>
<p>Password: <input type="password" name="password" /></p>
<p><input type="submit" value="登陆" /></p>
</form>

我们的处理里面的SQL可能是这样的:

String username = "jack";
String password = "123456";
String sql = "select * from user where username = '" + username + "' and password = '" + password + "'";

如果用户的输入的用户名如下,密码任意

myuser' or 'foo' = 'foo' --

那么我们的SQL变成了如下所示:

select * from user where username ='myuser' or 'foo'=='foo' --'' and password='xxx'

在SQL里面--是注释标记,所以查询语句会在此中断。这就让攻击者在不知道任何合法用户名和密码的情况下成功登录了。

对于MSSQL还有更加危险的一种SQL注入,就是控制系统,下面这个可怕的例子将演示如何在某些版本的MSSQL数据库上执行系统命令。

String sql = "SELECT * FROM products WHERE name LIKE '%"+prod+"%'"
//execute sql

如果攻击提交

a%' exec master..xp_cmdshell 'net user test testpass /ADD' --

作为变量 prod的值,那么sql将会变成

String sql ="SELECT * FROM products WHERE name LIKE '%a%' exec master..xp_cmdshell 'net user test testpass /ADD'--%'"

MSSQL服务器会执行这条SQL语句,包括它后面那个用于向系统添加新用户的命令。如果这个程序是以sa运行而 MSSQLSERVER服务又有足够的权限的话,攻击者就可以获得一个系统帐号来访问主机了。

虽然以上的例子是针对某一特定的数据库系统的,但是这并不代表不能对其它数据库系统实施类似的攻击。针对这种安全漏洞,只要使用不同方法,各种数据库都有可能遭殃。

如何预防SQL注入

也许你会说攻击者要知道数据库结构的信息才能实施SQL注入攻击。确实如此,但没人能保证攻击者一定拿不到这些信息,一旦他们拿到了,数据库就存在泄露的危险。如果你在用开放源代码的软件包来访问数据库,比如论坛程序,攻击者就很容易得到相关的代码。如果这些代码设计不良的话,风险就更大了。目前Discuz、phpwind、phpcms等这些流行的开源程序都有被SQL注入攻击的先例。

这些攻击总是发生在安全性不高的代码上。所以,永远不要信任外界输入的数据,特别是来自于用户的数据,包括选择框、表单隐藏域和 cookie。就如上面的第一个例子那样,就算是正常的查询也有可能造成灾难。

SQL注入攻击的危害这么大,那么该如何来防治呢?下面这些建议或许对防治SQL注入有一定的帮助。

  1. 严格限制Web应用的数据库的操作权限,给此用户提供仅仅能够满足其工作的最低权限,从而最大限度的减少注入攻击对数据库的危害。
  2. 检查输入的数据是否具有所期望的数据格式,严格限制变量的类型,例如使用regexp包进行一些匹配处理,或者使用strconv包对字符串转化成其他基本类型的数据进行判断。
  3. 对进入数据库的特殊字符('"\尖括号&*;等)进行转义处理,或编码转换
  4. 所有的查询语句建议使用数据库提供的参数化查询接口,参数化的语句使用参数而不是将用户输入变量嵌入到SQL语句中,即不要直接拼接SQL语句。例如使用database/sql里面的查询函数PrepareQuery,或者Exec(query string, args ...interface{})
  5. 在应用发布之前建议使用专业的SQL注入检测工具进行检测,以及时修补被发现的SQL注入漏洞。网上有很多这方面的开源工具,例如sqlmap、SQLninja等。
  6. 避免网站打印出SQL错误信息,比如类型错误、字段不匹配等,把代码里的SQL语句暴露出来,以防止攻击者利用这些错误信息进行SQL注入。

总结

通过上面的示例我们可以知道,SQL注入是危害相当大的安全漏洞。所以对于我们平常编写的Web应用,应该对于每一个小细节都要非常重视,细节决定命运,生活如此,编写Web应用也是这样。

时间: 2025-01-19 15:28:02

避免SQL注入的相关文章

SQL预编译和SQL注入

再说SQL预编译: 最近用go语言时,学习了一下数据库连接的库,这里总结一下SQL预编译相关的知识.貌似网上都是建议使用预编译,我也觉得这种做法靠谱. 先谈 SQL注入: SQL注入攻击指的是通过构建特殊的输入作为参数传入Web应用程序,而这些输入大都是SQL语法里的一些组合,通过让原SQL改变了语义,达到欺骗服务器执行恶意的SQL命令.其主要原因是程序没有细致地过滤用户输入的数据,致使非法数据侵入系统. 其实,反过来考虑,这也是SQL这类解释性语言本身的缺陷,安全和易用性总是相对的.类似的Sh

ASP通用防注入代码.杜绝SQL注入隐患.提升网站安全

ASP通用防注入代码.杜绝SQL注入隐患.提升网站安全 <% '''''''''''''''''''''''''''''''''''''''''''''''' 'ASP通用防注入代码 '您可以把该代码COPY到头文件中.也可以单独作 '为一个文件存在,每次调用使用 '作者:y3gu - 2005-7-29 '''''''''''''''''''''''''''''''''''''''''''''''' Dim GetFlag Rem(提交方式) Dim ErrorSql Rem(非法字符) Di

SQL注入攻击:防御和检查SQL注入的手段

虽然前面有许多文章讨论了SQL注入,但今天所讨论的内容也许可帮助你检查自己的服务器,并采取相应防范措施.知彼知己,方可取胜.首先要清楚SQL注入攻击有哪些种类. 观察近来的一些安全事件及其后果,安全专家们已经得到一个结论,这些威胁主要是通过SQL注入造成的.虽然前面有许多文章讨论了SQL注入,但今天所讨论的内容也许可帮助你检查自己的服务器,并采取相应防范措施. SQL注入攻击的种类 知彼知己,方可取胜.首先要清楚SQL注入攻击有哪些种类. 1.没有正确过滤转义字符 在用户的输入没有为转义字符过滤

关于SQL注入的几类错误和产生的原理

对于注入而言,错误提示是极其重要.所谓错误提示是指和正确页面不同的结果反馈,高手是很重视这个一点的,这对于注入点的精准判断至关重要.本问讨论下关于几类错误和他产生的原理,希望对读者有所帮助. 错误提示主要有逻辑错误和语法错误以及脚本运行错误三类. 一:逻辑错误 简单的例子是1=1 1=2这两个,1=1与1=2页面不同的原理是什么?以$sql = "select * from news where id=$_GET[id]"为例. select * from news where id=

利用SQL注入,通过dbo获得SQL管理权限和系统权限

我做了如下测试:(1) http://www.xxx.com/new/new.asp?id=49' Microsoft OLE DB Provider for ODBC Drivers 错误 '80040e14[Microsoft][ODBC Microsoft Access Driver] 字符串的语法错误 在查询表达式 'ID=49'' 中. /new.asp,行36 (2) http://www.xxx.com/new/new.asp?id=49 and 1=1(正常返回页面) (3) h

鲜为人知的SQL注入技巧

技巧|sql注入 1.关于Openrowset和Opendatasource2.关于Msdasql两次请求的问题3.可怕的后门        下面我要谈到一些Sqlserver新的Bug,虽然本人经过长时间的努力,当然也有点幸运的 成分在内,才得以发现,不敢一个人独享,拿出来请大家鉴别. 1.关于Openrowset和Opendatasource 可能这个技巧早有人已经会了,就是利用openrowset发送本地命令.通常我们的用 法是(包括MSDN的列子)如下: select * from op

ASP.NET优化:Sql注入和Html注入的黑帽SEO

黑帽(black hat)SEO主要是指采取"不怎么道德"(暂时就这么形容吧!)的方式进行搜索引擎优化. 1. 注入攻击,包括Sql注入和Html注入.我经常能看到对Sql注入防范的谈论,但对于Html注入,很多人并没有引起足够的重视.为了展示Html注入的效果,我们模仿了一个常见的留言本功能. 首先,在页面声明中添加两个属性设置EnableEventValidation="false" ValidateRequest="false" ,这很关键

批量替换sqlserver数据库挂马字段并防范sql注入攻击的代码

首先备份数据库,以防不必要的损失.而后对所有被挂马的小于8000字符的varchar字段执行 复制代码 代码如下: update 表名 set 字段名=replace(字段名,'<Script Src=http://c.n%75clear3.com/css/c.js></Script>','') 其中<Script Src=http://c.n%75clear3.com/css/c.js></Script>为挂马字段.执行后挂马字段被清除.但是有部分字段,比

SQL注入与ASP木马上传

木马|上传 SQL注入后,如何上传木马,一直是比较头疼的事,我这里提供上传木马的一种另一种方法.1.SQL注入的时候,用xp_cmdshell 向服务器上写入一个能写文件的asp文件.文件内容:<%Set objFSO = Server.createObject("Scripting.FileSystemObject")Set objCountFile=objFSO.createTextFile(request("mypath"),True)objCountF

入门:防范SQL注入攻击的新办法

近段时间由于修改一个ASP程序(有SQL注入漏洞),在网上找了很多相关的一些防范办法,都不近人意,所以我将现在网上的一些方法综合改良了一下,写出这个ASP函数,供大家参考. 以下是引用片段: Function SafeRequest(ParaName)  Dim ParaValue  ParaValue=Request(ParaName) if IsNumeric(ParaValue) = True then SafeRequest=ParaValue exit Function elseIf