按照百度说法,SQL注入是通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。其实就是就是提交精心构造的数据库语句,使其反馈一些有用的数据。说白了就是去欺骗数据库,假如只有web服务器的话,是没法进行SQL注入的。
网上常用的注入手法有两种,一种是猜测,让数据库暴出用户名、密码等信息;另一种直接绕过认证,取得权限。相对应,要想修复此类漏洞,就必须禁止特殊数据的提交或将特殊提交的数据修改。
下面是不同脚本语言下的防注入过滤代码,其实思想是一致的。
1、 PHP防注入过滤代码
/*************************
说明: 判断传递的变量中是否含有非法字符 如$_POST、$_GET
功能: 防注入
使用方法: 将下列代码保存为ak,php,调用方式 在数据提交页加上include("ak.php");
**************************/
<?php function dowith_sql($str) //实现将特征码两边加. { $refuse_str="exec|and|or|select|update|from|where|order|by|*|delete|'|insert|into|values|create|table| database|set|char|asc|cast|declare|<script|script|iframe|3bomb|c.js|;"; |
上面的防注入的方法只是防了GET与POST方法提交的数据,但是,WEB服务器读取数据的顺序是,先取GET中的数据,没有再去POST中的数据,没有还会再去COOKIES中的数据,上面的代码还没有防cookies注入。防cookies注入就比较简单了,cookies的id值一般只为阿拉伯数字,但是cookies注入必须得在id中构造代码,只要在获得参数UID后,对其进行过滤就可以了,代码如下:
<?php |
将上述代码保存为hk.php。所以在平时应用时,在网页上加上include("ak.php");与include("hk.php");
2、asp防注入过滤代码
'--------说明------------------
'使用方法: 在需要防注的页面头部用 <!--#Include File="sql2.asp"-->包含就可以了
'友情提示:把代码复制到CONN.asp(数据库连接文件) 那么,只要包含了CONN的所有文件都防注了
<% For xf_Xh=0 To Ubound(xf_Inf) Response.Write "操作页面:"&Request.ServerVariables("URL")&"<br>" |
同样,再将cookies防一下,代码加在数据提交页。
if(Request.Cookies["uid"]!=null) { uid=Request.Cookies["uid"].value; isnumeric cooidesID = new isnumeric(); //这是一个类 if (cooidesID.reIsnumeric(ruid)) //如果是数字就运行下面的 { string str="select * from userTable where id="+uid; ... } } |
3、 JSP防注入过滤代码
<script language="javascript"> <!-- var url = location.search; // 函数location.search作用是取?之后的参数值,取得 QueryString 部分 var re=/^?(.*)(select%20|insert%20|delete%20from%20|count(|drop%20table|update%20truncate%20|asc(|mid(|char(|xp_cmdshell|exec%20master|net%20localgroup%20administrators|"|:|net%20user||%20or%20)(.*)$/gi; //定义特殊字符串 var e = re.test(url); //test()字符串中是否有匹配正则表达式的子字符串。返回true或false。 if(e) { alert("地址中含有非法字符~"); location.href="error.asp"; } //--> <script> |
当然,我们也可以定义过滤函数,直接应用到用户名、密码等提交的数据参数上,函数如下:
function checkuseravoid(str){ var inj_str="‘|and|exec|insert|select|delete|update|count|*|%|chr|mid|master|truncate|char|declare|;|or|-|+|,"; var sarray=new Array(); sarray=inj_str.split('|'); for (var i=0 ;i <inj_stra.length ;i++ ) { if (str.indexOf(inj_stra)>=0) return true; } return false; } |
4、C#防注入过滤代码
//这个例子里暂定为=号和号,可继续添加 bool CheckParams(params object[] args) { string[] Lawlesses={"=",""}; if(Lawlesses==null||Lawlesses.Length<=0)return true; |
构造正则表达式,例:Lawlesses是=号和号,则正则表达式为 .*[=}].*
另外,由于我是想做通用而且容易修改的函数,所以多了一步由字符数组到正则表达式,实际使用中,直接写正则表达式亦可;
string str_Regex=".*["; for(int i=0;i< Lawlesses.Length-1;i++) str_Regex+=Lawlesses+"|"; str_Regex+=Lawlesses[Lawlesses.Length-1]+"].*"; // foreach(object arg in args) { if(arg is string) //如果是字符串,直接检查 { if(Regex.Matches(arg.ToString(),str_Regex).Count>0) return false; } else if(arg is ICollection) //如果是一个集合,则检查集合内元素是否字符串,是字符串,就进行检查 { foreach(object obj in (ICollection)arg) { if(obj is string) { if(Regex.Matches(obj.ToString(),str_Regex).Count>0) return false; } } } } return true; |