SQL注入(二)

接上一篇SQL注入(一)的内容说说防范SQL5

5.限制输入长度  

  如果在Web页面上使用文本框收集用户输入的数据,使用文本框的MaxLength属性来限制用户输入过长的字符也是一个很好的方法,因为用户的输入不够长,也就减少了贴入大量脚本的可能性。程序员可以针对需要收集的数据类型作出一个相应的限制策略。

6.URL重写技术

        我们利用URL重写技术过滤一些SQL注入字符,从而达到防御SQL注入。因为许多SQL注入是从URL输入发生的。

7.传递参数尽量不是字符

  假设我们显示一篇新闻的页面,从URL传递参数中获得newid我们可能会随手写下下面的代码:   

  string newsid = Request.QueryString["newsid"];
  string newssql = "select * from news where newsid=" + newsid;

 

  如果传递过来的参数是数字字符就没有问题。但是如果传递过来的newsid“1 delete from table ”的话,那么sql的值就变成了“select * from table where newsid=1 delete from news”。发生注入成功。但是这里改为

        int newsid=int.Parse(Request.QueryString["newsid"].ToString());

        string newssql = "select * from news where newsid=" + newsid.Tostring();

        这里如果还是上面"1 delete from table "会发生错误,因为在转换时候出现了错误

        从上面的一个小例子,我们得出在传递参数时候尽量不要用字符,免得被注入。 

 

  最后是我想扩展下利用URL重写技术来过滤一些SQL注入字符,首先这里有一篇关于URL重写的文章,我的基本思想是可以利用它,屏蔽一些危险的SQL注入字符串,这些字符串我们可以人为的设定,毕竟我们还是根据特定的环境设定我们防御措施。首先我们在ModuleRewriter类中的Rewrite函数得到绝对的URL判断其中是否有危险字符,如果有我们就将它链接到一个提示用户您输入危险的URL地址。如果不是我们继续判断是否触发了其他的URL重写的规则,触发了就重写。这样就大致上能在URL上防御危险字符

代码
<RewriterConfig>
<Rules>
<RewriterRule>
<LookFor>~/d(\d+)\.aspx</LookFor>
<SendTo>~/Default_sql_error.aspx</SendTo>
</RewriterRule>
<RewriterRule>
<LookFor>~/d(\d+)\.aspx</LookFor>
<SendTo>~/Default2.aspx</SendTo>
</RewriterRule>
</Rules>
</RewriterConfig>

上面是要在web.config配置文件加上的内容,这里我加上了两个重写规则,第一个规则是专门针对满足这个正则表达式的页面URL查看是否有危险字符,有危险字符就会发送到Default_sql_error.aspx页面,来示警。这里我假定会发生危险字符注入的页面时以"d"字符开头并加上数字的页面(这里我们可以根据实际情况自己定义,看哪些页面URL容易发生我们就制定这些页面的正则表达式),第二个是一般URL重写。因为这里我采用的是HTTP模块执行URL重写,所以加上<httpModules></httpModules>这一块。

         第二步就是要在重写Rewrite函数了

 

protected override void Rewrite(string requestedPath, System.Web.HttpApplication app)
{
// 获得配置规则
RewriterRuleCollection rules = RewriterConfiguration.GetConfig().Rules;

Uri url
= app.Request.Url;

// 判断url 中是否含有SQL 注入攻击敏感的字符或字符串,如果存在,sqlatFlag = 1 ;
string urlstr = url.AbsoluteUri;
int sqlatFlag = 0;
string words = "exec ,xp ,sp ,declare ,cmd ,Union ,--";

// 如果还有其他敏感的字符或者符号,可以加入上面这行字符串中
string[] split = words.Split(',');
foreach (string s in split)
{
if (urlstr.IndexOf(s.ToUpper()) > 0)
{
sqlatFlag
= 1;
break;
}
}
if (sqlatFlag == 1)
{
// 创建regex
Regex re = new Regex(rules[0].SendTo, RegexOptions.IgnoreCase);
// 找到匹配的规则,进行必要的替换
string sendToUrl = RewriterUtils.ResolveUrl(app.Context.Request.ApplicationPath, re.ToString());
// 重写URL
RewriterUtils.RewriteUrl(app.Context, sendToUrl);
//RewriterUtils.RewriteUrl(app.Context, rules[0].SendTo);
}
else
{
// 遍历除rules[0 ]以外的其他URL 重写规则
for (int i = 1; i < rules.Count; i++)
{
// 获得要查找的模式,并且解析URL (转换为相应的目录)
string lookFor = "^" + RewriterUtils.ResolveUrl(app.Context.Request.ApplicationPath, rules[i].LookFor) + "$";
// 创建regex
Regex re = new Regex(lookFor, RegexOptions.IgnoreCase);
// 查看是否找到了匹配的规则
if (re.IsMatch(requestedPath))
{
// 找到了匹配的规则, 进行必要的替换
string sendToUrl = RewriterUtils.ResolveUrl(app.Context.Request.ApplicationPath, re.Replace(requestedPath, rules[i].SendTo));
// 重写URL
RewriterUtils.RewriteUrl(app.Context, sendToUrl);
break;
// 退出For 循环
}
}
}
}

 

 

那么下一步就是检验例子了

首先我们输入http://localhost:4563/web/Default.aspx?id=1;-- 

这样http://localhost:4563/web/Default.aspx?id=1;-- 没有改变,就会显示Default_sql_error.aspx里内容您输入了危险字符 
再输入http://localhost:4563/web/D11.aspx就会显示 Default2.aspx内容,因为这里触发了第二个重写规则

 试验成功。

 

  当然用URLSQL只是我想到一种怪癖思路,大家如果有什么特别方法可以共同考论一下,还是引用前辈们话见招拆招遇到实际的问题我们就根据实际情况解决,选用那个最实用的方法。

 本次用到的  

posted @ 2009-12-16 10:19  胡佳180815  阅读(5758)  评论(19编辑  收藏  举报