ASP.NET中防止注入攻击-程序员宅基地

技术标签: c#  数据库  

概述 : 
 你应该在程序中验证所有的不信任输入.你应该假定所有的用户输入都是非法的.用户可以在应用程序中提供表单字段,查询字串,客户端cookies和浏览器环境值比如用户代理字串和IP地址等.

  弱输入校验通常为注入攻击提供了机会.下面是常见的利用弱输入校验或无输入校验进行攻击的手段.

SQL 注入(SQL injection). 如果你使用用户的输入值来动态构造SQL语句,那么数据库可能执行攻击性的有害SQL语句.

跨站脚本(Cross-site scripting). 跨站脚本攻击利用网页验证漏洞注入客户端脚本.接下来这些代码被发送到受信任的客户端电脑上并被浏览器解释执行.因为这些代码来自受信任的站点,所以浏览器无法得知这些代码是有害的.

未授权的文件访问(Unauthorized file access).如果你的代码从调用者那里接受输入,恶意用户可以看到你对文件的操作过程从而访问那些受保护的文件或者使用你的代码注入非法数据.

  注意 : 注入攻击可通过使用HTTP或HTTPS Secure Socket Layer(SSL) 连接. 传输加密技术不能用来防御攻击.

  通常的输入验证方法总结如下.你应在所有的需要通过网络输入的地方进行验证,比如文本框和其它表单输入字段, 查询字串参数,cookies,服务器端变量和网络方法参数.注意,过滤策略应该是只允许正确的输入然后拒绝非法输入.这是因为定义正确的输入策略比过滤所有的非法输入要容易,那通常很难包括所有的非法输入.

  通入如下几个方面验证输入内容:

约束.验证是否输入的是正确的类型,字符长度,格式和范围.可以应用ASP.NET验证控件来约束服务器控件输入.约束其它来源的输入可以使用正则表达式和自定义的验证规则.

拒绝.检测已知的有害数据输入并拒绝.

过滤.有时候你会希望过滤掉用户输入中那些有安全隐患的那些部分.例如,你的程序允许自由格式的输入,比如备注字段,你会允许特定的安全HTML标记象<b>,<i>及其它的HTML标记.

  步骤提要

  通过以下步骤保护你的ASP.NET程序不受注入式攻击危害 :

第一步.使用ASP.NET请求验证.
第二步.约束输入.
第三步.对不安全的输出进行编码.
第四步.对SQL查询语句使用命令参数.
第五步.验证ASP.NET的出错信息没有泄漏至客户端.

  下面的章节将对这些步骤进行详细讨论.

  第一步.使用ASP.NET请求验证.

  默认地,ASP.NET 1.1和2.0请求验证会对送至服务器的数据检测是否含有HTML标记元素和保留字符.这可以防止用户向程序中输入脚本.请求验证会对照一个有潜在威胁的 字符串列表进行匹配,如果发现异常它会抛出一个HttpRequestValidationException类型的异常.

  你可以在你的web.config文件中的<pages>元素中加入validateRequest="false" 或在单独的页面的 @ Pages元素里面设置ValidateRequest = "false"来禁用此项功能.

  如果你想禁用请求验证功能,你可以仅在需要的页面禁用它.比如你在程序页面上包含一个可接受HTML格式输入的字段.

  确定在Machine.config文件中请求验证功能被打开.
 
  请求验证功能在ASP.NET中被默认启用.你可以在Machine.config.comments文件中看到如下的默认设置.

<pages validateRequest = "true" ... />

  确认你没有修改你的服务器的Machine.config和应用程序的Web.config文件里的默认设置.

  ASP.NET请求验证

  你可以测试请求验证的作用.创建一个ASP.NET页面通过设置ValidateRequest = "fasle"禁用请求验证,代码如下 : <% @ Language="C#" ValidateRequest="false" %>
<HTML>
<script runat="server">
void btnSubmit_Click(Object sender, EventArgs e)


{

//
If ValidateRequest is false, then 'hello' is displayed

//
If ValidateRequest is true, then ASP.NET returns an exception

Response.Write(txtString.Text);
}
</script>
<body>
<form id="form1" runat="server">
<ASP:TextBox id="txtString" runat="server"
Text="<script>alert('hello');</script>" />
<ASP:Button id="btnSubmit" runat="server" OnClick="btnSubmit_Click"
Text="Submit" />
</form>
</body>
</HTML> 当你运行页面的时候,"Hello"被显示在一个消息框中,因为在txtString中的脚本被执行并被客户端的浏览器处理.

  如果你设置ValidateRequest = "true" 或者移除ValidateRequest页面属性,ASP.NET请求验证会拒绝脚本输入并抛出一个象下面这样的错误信息.
  A potentially dangerous Request.Form value was detected from the client (txtString="<script>alert('hello").

  注意 不要仅仅依赖请求验证功能,而只是把它作为自定验证的辅导手段.
第二步.约束输入

  要约束输入通过如下方法 :

使用服务器端的输入验证.不要依赖于客户端的验证,因为它很容易就被绕过.使用客户端验证是为了减少页面返住次数提升性能,改进用户体验.
验证输入的长度,范围,格式和类型.确保输入内容是符合要求的正确内容.
使用强数据类型.为数字类型的输入指定如Integer或者Double的类型.为字符输入指定为String数据类型.为日期时间输入指定DateTime类型.

  要验证表单里面的HTML控件输入字段,在服务器端代码中进行验证,使用Regex正则表达式类型可以帮助约束字符输入.下面的章节介绍如何约束普通输入类型的变量.

验证字符串字段

要验证字符串字段,如姓名,地址,传真,生份证号码,使用正则表达式.
约束可接受的字符范围.
启动格式规则.例如,基于模式的字段如税号,邮编,邮递区号需要规定的字符模式.
验证长度.

  使用正则表达式验证控件(RegularExpresionValidator)

  要使用则表达式验证控件需要设置待验证的控件名(ControlToValidate),验证表达式(ValidationExpression)和出错提示(ErrorMessage).相关的属性设置请看下面的代码示例.

<form id="WebForm" method="post" runat="server">
<ASP:TextBox id="txtName" runat="server"></ASP:TextBox>
<ASP:RegularExpressionValidator id="nameRegex" runat="server"
ControlToValidate="txtName"
ValidationExpression="^[a-zA-Z'./s]{1,40}$"
ErrorMessage="Invalid name">
</ASP:regularexpressionvalidator>
</form>

  在上面的代码中,正则表达式被用于限定输入的名字为字母(允许大写字母和小写字母),空格,单名省略号象O'Dell和句点.此外,输入的字符长度被限定在40个字符.

  注意 正则表达式验证控件(RegularExpressionValidator)会自动加入脱字符(^)和美元符号($)作为开始和结束的分隔符.如果你没有在自定义的表达式中加入他们那么最好加入.加入分隔符只是为了让你的表达式得到想要的那部分数据内容.

  使用正则表达式类(Regex Class)

  如果你没有使用服务器端的控件(意味着你不能使用验证控件),或者你需要其它的输入字段源而非表单字段(比如查询字串参数和cookies),那么你可以使用正则表达式类(Regex class).

  使用正则表达式类

加入使用using前缀的语句导入System.Text.RegularExpressions命名空间.
确认正则表达式包含"^"和"$"(字串开始处,字串结束处).
调用Regex类的IsMatch方法,下面是代码示例.
//
Instance method:

Regex reg = new Regex( @ "^[a-zA-Z'./s]{1,40}$");
Response.Write(reg.IsMatch(txtName.Text));
//
Static method:

if (!Regex.IsMatch(txtName.Text, @ "^[a-zA-Z'./s]{1,40}$"))


{

//
Name does not match expression

}

  如果你不能把经常使用的正则表达式缓存起来,你应该使用IsMatch静态方法来改进性能防止不必要的对象创建过程.

  验证数字字段

  在大多数情况下,应该验证数字的输入和范围.使用服务器控件验证数字字段的输入和范围,使用RangeValidator控件.RangeValidator支持货币,日期,整型,双精度和字符串类型的数据.

  使用RangeValidator控件需要设置需要验证的控件名(ControlToValidate),类型(Type),最小值 (MinimumValue),最大值(MaximumValue),和出错提示信息(ErrorMessage)属性.下面是代码示例 :

<ASP:RangeValidator
ID="RangeValidator1"
Runat="server"
ErrorMessage="Invalid range. Number must be between 0 and 255."
ControlToValidate="rangeInput"
MaximumValue="255"
MinimumValue="0" Type="Integer" />

  如果你没使用服务器控件,你可以将输入值转化成整型再进行验证来完成对数字的范围验证.例如,要验证一个整数是否合法,使用 ASP.NET2.0提供的新方法Int32.TryParse将输入值转化为System.Int32的变量类型.这个方法会在转换失败时返回 false.

Int32 i;
if (Int32.TryParse(txtInput.Text, out i) == false)


{

//
Conversion failed

}

  如果你使用早先的ASP.NET版本,可以在try/catch语句块中 使用Int32.Parse或者Convert.ToInt32方法并可以在转换失败时处理抛出的FormatException错误.

  下面的示例代码演示了如何验证来自HTML文本框的整数类型的类型和范围.

<% @  Page Language="C#" %>
<script runat="server">
void Page_Load(object sender, EventArgs e)


{
if (Request.RequestType == "POST")


{
int i;
if (Int32.TryParse(Request.F
orm["integerTxt"], out i) == true)

{

//
TryParse returns true if the conversion succeeds

if ((0 <= i && i <= 255) == true)

{
Response.Write("Input data is valid.");
}
else
Response.Write("Input data is out of range");
}
else
Response.Write("Input data is not an integer");
}
}

</script>

<HTML>
<body>
<form id="form1" action="NumericInput.ASPx" method="post">
<div>
Enter an integer between 0 and 255:
<input name="integerTxt" type="text" />
<input name="Submit" type="submit" value="submit" />
</div>
</form>
</body>
</HTML>

你应该假定所有的用户输入都是非法的.用户可以在应用程序中提供表单字段,查询字串,客户端cookies和浏览器环境值比如用户代理字串和IP地址等.

--------------------------------------------------------------------------------

  验证日期字段

  你需要验证日期字段是否是正确的类型.在大多数情况下,你也需要验证它们的范围,如验证它们是否是将来或是过去的时间.如果你使用服务器控件来 捕获一个日期输入值,同时你希望这个值在一个特定的范围内,你可以使用范围验证控件(RangeValidator)并设置它允许的类型为Date类型. 这个控件允许你指定一个特殊的时间段通过设置起始的时刻.如果你需要以今天的时间作为参照来验证,比如验证一个时间是在将来还是过去,你可以使用 CustomValidator验证控件。

  使用CustomValidator控件来验证一个日期需要设置ControlToValidate和ErrorMessage属性,在OnServerValidate事件中指定一个自定义的验证逻辑方法.下面是示例代码.

<% @  Page Language="C#" %>
<script runat="server">
void ValidateDateInFuture(object source, ServerValidateEventArgs args)


{
DateTime dt;


//
Check for valid date and that the date is in the future

if ((DateTime.TryParse(args.Value, out dt) == false) ||
(dt <= DateTime.Today))


{
args.IsValid = false;
}
}

</script>

<HTML>
<body>
<form id="form1" runat="server">
<div>
<ASP:Label ID="Label1" Runat="server"
Text="Future Date:"></ASP:Label>
<ASP:TextBox ID="futureDatetxt" Runat="server"></ASP:TextBox>
<ASP:CustomValidator
ID="CustomValidator1" Runat="server"
ErrorMessage="Invalid date. Enter a date in the future."
ControlToValidate="futureDatetxt"
OnServerValidate="ValidateDateInFuture">
</ASP:CustomValidator>
<br />
<ASP:Button ID="submitBtn" Runat="server" Text="Submit" />
</div>
</form>
</body>
</HTML>

  注意 上面的代码使用的方法DateTime.TryParse是ASP.NET2.0提供的新方法.

  过滤自由文本字段

  过滤输入,你需要使不安全的输入不被当作代码来对待.例如,你的程序使用户不能读取共享数据库内的数据,你首先需要过滤数据使它们在输出的时候没有危险.使用HttpUtility.HTMLEncode方法先对输入值进行编码.

  允许有限的输入HTML代码


在 @  Page页面元素内加以下字段ValidateRequest = "false"禁用ASP.NET请求验证
使用HTMLEncode方法对输入的字符串进行编码
使用StringBuilder对象,调用它的Replace方法对字符中的HTML进行替换
  下面的代码给出了这种办法的示例.此页面设置ValidateRequest = "fasle"禁用了ASP.NET请求验证.它的HTML编码为了显示简单的文本格式允许使用<b>和<i>标记.

<% @  Page Language="C#" ValidateRequest="false"%>
<script runat="server">
void submitBtn_Click(object sender, EventArgs e)


{

//
Encode the string input

StringBuilder sb = new StringBuilder(
HttpUtility.HTMLEncode(HTMLInputTxt.Text));

//
Selectively allow and <i>

sb.Replace("<b>", "<b>");
sb.Replace("</b>", "");
sb.Replace("<i>", "<i>");
sb.Replace("</i>", "");
Response.Write(sb.ToString());
}
</script>
<HTML>
<body>
<form id="form1" runat="server">
<div>
<ASP:TextBox ID="HTMLInputTxt" Runat="server"
TextMode="MultiLine" Width="318px"
Height="168px"></ASP:TextBox>
<ASP:Button ID="submitBtn" Runat="server"
Text="Submit" OnClick="submitBtn_Click" />
</div>
</form>
</body>
</HTML>

转载于:https://www.cnblogs.com/ttlive/archive/2008/05/31/2191390.html

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_30651273/article/details/96184606

智能推荐

Java垃圾回收精粹——Part2-程序员宅基地

文章浏览阅读701次。在第2部分里介绍了Hotspot中的堆结构、对象分配以及次要回收。Hotspot中的堆结构理解不同的收集器的工作方式,是探讨Java堆结构如何支持分代机制的最好的方式。伊甸区(Eden)的大部分对象都是刚刚被分配的。幸存区(survivor)用来临时存储那些从伊甸区里幸存下来的对象。当我们讨论完次要回收(minor collections)后将描述幸存区的用途。伊甸区和幸存区统称为“年

152 页简明《计算机视觉》入门教程,带你回顾 CV 发展脉络_本文是计算机科学家christoph rasche撰写的一份计算机视觉方面的系列教程,从-程序员宅基地

文章浏览阅读305次。本文是计算机科学家Christoph Rasche撰写的一份计算机视觉方面的系列教程,从传统的图像处理、特征提取到近几年很热的深度神经网络,以及深度学习方法在目标检测、图像检索、图像分割、目标跟踪等一系列前沿的介绍。书本里本文是计算机科学家Christoph Rasche撰写的一份计算机视觉方面的系列教程,从传统的图像处理、特征提取到近几年很热的深度神经网络,以及深度学习方法在目标检测、图像检索、..._本文是计算机科学家christoph rasche撰写的一份计算机视觉方面的系列教程,从

Codeforces Round #499 (Div. 2) C. Fly 数学公式推导_codeforces c.fly-程序员宅基地

文章浏览阅读267次。Natasha is going to fly on a rocket to Mars and return to Earth. Also, on the way to Mars, she will land on n − 2 intermediate planets. Formally: we number all the planets from 1 to n . ..._codeforces c.fly

Emoji表情符号兼容方案(适用ios,android,wp等平台)-程序员宅基地

文章浏览阅读138次。http://blog.csdn.net/qdkfriend/article/details/7576524 Emoji表情符号兼容方案一 什么是Emoji emoji就是表情符号;词义来自日语(えもじ,e-moji,moji在日语中的含义是字符)  表情符号现已普遍应用于手机短信和网络聊天软件。  emoji表情符号,在外国的手机短信里面已经是很流行使用的一种表情..._win10系统的emoji表情怎样才能和安卓手机的一样

毕设分享 基于大数据的游数据分析可视化系统(源码分享)_基于大数据的网络安全可视化系统项目源码-程序员宅基地

文章浏览阅读179次。今天学长向大家分享一个毕业设计项目毕业设计 基于大数据的游数据分析可视化系统(源码分享)演示效果毕业设计 大同旅游数据分析可视化系统数据可视化是数据处理中的重要部分Django是一个基于Web的应用框架,由python编写。Web开发的基础是B/S架构,它通过前后端配合,将后台服务器的数据在浏览器上展现给前台用户的应用。_基于大数据的网络安全可视化系统项目源码

数据压缩第九次作业:总结最小二乘法——梯度下降法、牛顿法、高斯牛顿法_已知f(x),求f(x+derta x)-程序员宅基地

文章浏览阅读1.9k次。任务2:总结最小二乘法——梯度下降法、牛顿法、高斯牛顿法最小二乘法定义:最小二乘法(又称最小平方法)是一种数学优化技术。它通过最小化误差的平方和寻找数据的最佳函数匹配。利用最小二乘法可以简便地求得未知的数据,并使得这些求得的数据与实际数据之间误差的平方和为最小。最小二乘法还可用于曲线拟合。其他一些优化问题也可通过最小化能量或最大化熵用最小二乘法来表达。一、如何理解最小二乘法:首先,最小二乘法的思想可以用一个例子来理解:假设我们对一个大小约等于10的数据有y1,y2,y3,y4,y5这样的5个估计值_已知f(x),求f(x+derta x)

随便推点

如何在Ubuntu 14.04当中将Bind配置为仅权威DNS服务器_auth-nxdomain no;-程序员宅基地

文章浏览阅读1.4k次。提供:ZStack云计算 系列教程本教程为DNS管理介绍系列七篇中的第五篇。内容介绍DNS,或者称为域名系统,往往成为学习网站与服务器配置中的一大难点。尽管很多人都会使用由托管厂商或者域名注册商提供的DNS服务器,但建立自己的DNS服务器亦能带来诸多不容忽视的助益。在本篇教程中,我们将探讨如何在Ubuntu 14.04当中安装Bind9 DNS服务器并将其配置为仅权威DNS服务器。作为示例,我们将立_auth-nxdomain no;

IDEA快捷键、自定义模板_idea 设置自定义快捷键模板-程序员宅基地

文章浏览阅读377次,点赞8次,收藏7次。快速格式化代码(改善代码格式,砍起来更好看) ctrl + alt + L。【第一次是添加注释,第二次是取消注释】快速运行程序 自己定义 shift +在java中找到+号 进行添加。将光标放在一个方法上,输入。导入该行需要的类 先配置。ctrl + 左键 ,查看一个类的层级关系。学习继承后,非常有用。还有很多其它的快捷键。自己的定义的一些模板。_idea 设置自定义快捷键模板

Python 冒泡排序和快速排序(公开代码)-程序员宅基地

文章浏览阅读556次。Python 冒泡排序def bubble(n,list): #n默认为0 for i in range(0,len(list)-n-1): temporary_variable=0#设置临时变量 if list[i]>list[i+1]: temporary_variable=list[i + 1] list[i + 1]=list[i] list[i]=temporary_variab_python 冒泡排序和快速排序

Mysql 某个字段仅保留数字_mysql 只保留数字-程序员宅基地

文章浏览阅读4.4k次。**mysql 查询语句,针对字段去掉数字之外的内容仅保留数字的三种方式**1、使用cast函数转变数据类型select cast('[email protected]' as unsigned)结果:1234562、该方式未知原因(知道的小伙伴欢迎留言)select -(-'[email protected]')结果:1234563、字段后加0进行运算强转select "[email protected]"+0;结果:123456以上方式都有一个问题会存在数据舍弃例如,如果要完成_mysql 只保留数字

Cisco WLC无线控制器简单二层配置_wlcrrc-程序员宅基地

文章浏览阅读8.1k次,点赞3次,收藏8次。CISCO SYSTEMSEmbedded BIOS Version 1.0(12)12 07/23/08 10:37:30.75Low Memory: 632 KBHigh Memory: 251 MBPCI Device Table.Bus Dev Func VendID DevID Class Irq00 01 00 1022 2080 Host B..._wlcrrc