ASP.NET网页编程之在ASP.NET中避免注进打击[翻译]
你觉得学习.NET怎么样,我懂的少,问的可能很幼稚,见笑了啊:)asp.net|打击出处:MSDN翻译:云中城BLOG
使用局限:
ASP.NETvertion1.1
ASP.NETvertion2.0
提要:
文本次要先容怎样校验用户输出从而避免注进式打击.校验用户输出长短常需要的,几近一切程序级的打击都包括歹意输出的手腕.
你应当校验包含字段,查询字串参数,Cookie等统统用户输出项来回护你的程序免受注进打击.你得假定一切的用户输出都是歹意的,确保在服务器端对一切的用户输出举行校验.利用基于客户真个考证能够削减页面的住返次数,改善功能,改良用户体验,可是不要仅仅依附于此,由于客户真个考证很简单就能够被黑客骗已往.
为了考证输出内容,你应当为每个输出字段界说可承受的输出划定规矩.对照好的作法是从输出字段的长度,局限,格局,范例来作束缚.利用可承受的字符束缚列表而不长短法字符列表来束缚输出.利用不法字符列表束缚的体例欠好,是由于你几近不成能过滤一切的无害输出.
假如你必要承受HTML字符输出,最好利用HtmlEncode之类的办法将它举行编码确保平安再将它们显现出来.
内容:
目标
总括
分步实行提纲
第一步.利用ASP.NET哀求校验.
第二步.利用权用束缚输出.
第三步.对不平安的输出举行编码.
第四步.对Sql语句利用命令参数体例.
第五步.考证ASP.NET的毛病没有被前往客户端.
分外的资本
--------------------------------------------------------------------------------
目标:
对输出的字串长度,局限,格局和范例举行束缚.
在开辟ASP.NET程序时利用哀求考证避免注进打击.
利用ASP.NET考证控件举行输出考证.
对不平安的输入编码.
利用命令参数集形式避免注进打击.
避免毛病的具体信息被前往到客户端.
概述:
你应当在程序中考证一切的不信托输出.你应当假定一切的用户输出都长短法的.用户能够在使用程序中供应表单字段,查询字串,客户端cookies和扫瞄器情况值好比用户代办署理字串和IP地点等.
弱输出校验一般为注进打击供应了时机.上面是罕见的使用弱输出校验或无输出校验举行打击的手腕.
SQL注进(SQLinjection).假如你利用用户的输出值来静态机关SQL语句,那末数据库大概实行打击性的无害SQL语句.
跨站剧本(Cross-sitescripting).跨站剧本打击使用网页考证毛病注进客户端剧本.接上去这些代码被发送到受信托的客户端电脑上并被扫瞄器注释实行.由于这些代码来自受信托的站点,以是扫瞄器没法得知这些代码是无害的.
未受权的文件会见(Unauthorizedfileaccess).假如你的代码从挪用者那边承受输出,歹意用户能够看到你对文件的操纵历程从而会见那些受回护的文件大概利用你的代码注进不法数据.
注重:注进打击可经由过程利用HTTP或HTTPSSecureSocketLayer(SSL)毗连.传输加密手艺不克不及用来进攻打击.
一般的输出考证办法总结以下.你应在一切的必要经由过程收集输出的中央举行考证,好比文本框和别的表单输出字段,查询字串参数,cookies,服务器端变量和收集办法参数.注重,过滤战略应当是只同意准确的输出然后回绝不法输出.这是由于界说准确的输出战略比过滤一切的不法输出要简单,那一般很难包含一切的不法输出.
通进以下几个方面考证输出内容:
束缚.考证是不是输出的是准确的范例,字符长度,格局和局限.能够使用ASP.NET考证控件来束缚服务器控件输出.束缚别的来历的输出可使用正则表达式和自界说的考证划定规矩.
回绝.检测已知的无害数据输出并回绝.
过滤.偶然候你会但愿过滤失落用户输出中那些有平安隐患的那些部分.比方,你的程序同意自在格局的输出,好比备注字段,你会同意特定的平安HTML标志象<b>,<i>及别的的HTML标志.
步骤提纲
经由过程以下步骤回护你的ASP.NET程序不受注进式打击伤害:
第一步.利用ASP.NET哀求考证.
第二步.束缚输出.
第三步.对不平安的输入举行编码.
第四步.对SQL查询语句利用命令参数.
第五步.考证ASP.NET的堕落信息没有泄露至客户端.
上面的章节将对这些步骤举行具体会商.
第一步.利用ASP.NET哀求考证.
默许地,ASP.NET1.1和2.0哀求考证会对送至服务器的数据检测是不是含有HTML标志元素和保存字符.这能够避免用户向程序中输出剧本.哀求考证会对比一个有潜伏威逼的字符串列表举行婚配,假如发明非常它会抛出一个HttpRequestValidationException范例的非常.
你能够在你的web.config文件中的<pages>元素中到场validateRequest="false"或在独自的页面的@Pages元素内里设置ValidateRequest="false"来禁用此项功效.
假如你想禁用哀求考证功效,你能够仅在必要的页面禁用它.好比你在程序页面上包括一个可承受HTML格局输出的字段.
断定在Machine.config文件中哀求考证功效被翻开.
哀求考证功效在ASP.NET中被默许启用.你能够在Machine.config.comments文件中看到以下的默许设置.
<pagesvalidateRequest="true".../>
确认你没有修正你的服务器的Machine.config和使用程序的Web.config文件里的默许设置.
测试ASP.NET哀求考证
你能够测试哀求考证的感化.创立一个ASP.NET页面经由过程设置ValidateRequest="fasle"禁用哀求考证,代码以下:
<%@Language="C#"ValidateRequest="false"%>
<html>
<scriptrunat="server">
voidbtnSubmit_Click(Objectsender,EventArgse)
{
//IfValidateRequestisfalse,thenhelloisdisplayed
//IfValidateRequestistrue,thenASP.NETreturnsanexception
Response.Write(txtString.Text);
}
</script>
<body>
<formid="form1"runat="server">
<asp:TextBoxid="txtString"runat="server"
Text="<script>alert(hello);</script>"/>
<asp:Buttonid="btnSubmit"runat="server"
Text="Submit"/>
</form>
</body>
</html>
当你运转页面的时分,"Hello"被显现在一个动静框中,由于在txtString中的剧本被实行并被客户真个扫瞄器处置.
假如你设置ValidateRequest="true"大概移除ValidateRequest页面属性,ASP.NET哀求考证会回绝剧本输出并抛出一个象上面如许的毛病信息.
ApotentiallydangerousRequest.Formvaluewasdetectedfromtheclient(txtString="<script>alert(hello").
注重不要仅仅依附哀求考证功效,而只是把它作为自定考证的指点手腕.
第二步.束缚输出
要束缚输出经由过程以下办法:
利用服务器真个输出考证.不要依附于客户真个考证,由于它很简单就被绕过.利用客户端考证是为了削减页面返住次数提拔功能,改善用户体验.
考证输出的长度,局限,格局和范例.确保输出内容是切合请求的准确内容.
利用强数据范例.为数字范例的输出指定如Integer大概Double的范例.为字符输出指定为String数据范例.为日期工夫输出指定DateTime范例.
要考证表单内里的HTML控件输出字段,在服务器端代码中举行考证,利用Regex正则表达式范例能够匡助束缚字符输出.上面的章节先容怎样束缚一般输出范例的变量.
考证字符串字段
要考证字符串字段,如姓名,地点,传真,生份证号码,利用正则表达式.
束缚可承受的字符局限.
启动格局划定规矩.比方,基于形式的字段如税号,邮编,邮递区号必要划定的字符形式.
考证长度.
利用正则表达式考证控件(RegularExpresionValidator)
要利用则表达式考证控件必要设置待考证的控件名(ControlToValidate),考证表达式(ValidationExpression)和堕落提醒(ErrorMessage).相干的属性设置请看上面的代码示例.
<formid="WebForm"method="post"runat="server">
<asp:TextBoxid="txtName"runat="server"></asp:TextBox>
<asp:RegularExpressionValidatorid="nameRegex"runat="server"
ControlToValidate="txtName"
ValidationExpression="^{1,40}$"
ErrorMessage="Invalidname">
</asp:regularexpressionvalidator>
</form>
在下面的代码中,正则表达式被用于限制输出的名字为字母(同意年夜写字母和小写字母),空格,单名省略号象ODell和句点.别的,输出的字符长度被限制在40个字符.
注重正则表达式考证控件(RegularExpressionValidator)会主动到场脱字符(^)和美圆标记($)作为入手下手和停止的分开符.假如你没有在自界说的表达式中到场他们那末最好到场.到场分开符只是为了让你的表达式失掉想要的那部分数据内容.
利用正则表达式类(RegexClass)
假如你没有利用服务器真个控件(意味着你不克不及利用考证控件),大概你必要别的的输出字段源而非表单字段(好比查询字串参数和cookies),那末你可使用正则表达式类(Regexclass).
利用正则表达式类
到场利用using前缀的语句导进System.Text.RegularExpressions定名空间.
确认正则表达式包括"^"和"$"(字串入手下手处,字串停止处).
挪用Regex类的IsMatch办法,上面是代码示例.
//Instancemethod:
Regexreg=newRegex(@"^{1,40}$");
Response.Write(reg.IsMatch(txtName.Text));
//Staticmethod:
if(!Regex.IsMatch(txtName.Text,@"^{1,40}$"))
{
//Namedoesnotmatchexpression
}
假如你不克不及把常常利用的正则表达式缓存起来,你应当利用IsMatch静态办法来改善功能避免不用要的工具创立历程.
考证数字字段
在年夜多半情形下,应当考证数字的输出和局限.利用服务器控件考证数字字段的输出和局限,利用RangeValidator控件.RangeValidator撑持泉币,日期,整型,双精度和字符串范例的数据.
利用RangeValidator控件必要设置必要考证的控件名(ControlToValidate),范例(Type),最小值(MinimumValue),最年夜值(MaximumValue),和堕落提醒信息(ErrorMessage)属性.上面是代码示例:
<asp:RangeValidator
ID="RangeValidator1"
Runat="server"
ErrorMessage="Invalidrange.Numbermustbebetween0and255."
ControlToValidate="rangeInput"
MaximumValue="255"
MinimumValue="0"Type="Integer"/>
假如你没利用服务器控件,你能够将输出值转化成整型再举行考证来完成对数字的局限考证.比方,要考证一个整数是不是正当,利用ASP.NET2.0供应的新办法Int32.TryParse将输出值转化为System.Int32的变量范例.这个办法会在转换失利时前往false.
Int32i;
if(Int32.TryParse(txtInput.Text,outi)==false)
{
//Conversionfailed
}
假如你利用新近的ASP.NET版本,能够在try/catch语句块中利用Int32.Parse大概Convert.ToInt32办法并能够在转换失利时处置抛出的FormatException毛病.
上面的示例代码演示了怎样考证来自HTML文本框的整数范例的范例和局限.
<%@PageLanguage="C#"%>
<scriptrunat="server">
voidPage_Load(objectsender,EventArgse)
{
if(Request.RequestType=="POST")
{
inti;
if(Int32.TryParse(Request.Form["integerTxt"],outi)==true)
{
//TryParsereturnstrueiftheconversionsucceeds
if((0<=i&&i<=255)==true)
{
Response.Write("Inputdataisvalid.");
}
else
Response.Write("Inputdataisoutofrange");
}
else
Response.Write("Inputdataisnotaninteger");
}
}
</script>
<html>
<body>
<formid="form1"action="NumericInput.aspx"method="post">
<div>
Enteranintegerbetween0and255:
<inputname="integerTxt"type="text"/>
<inputname="Submit"type="submit"value="submit"/>
</div>
</form>
</body>
</html>
考证日期字段
你必要考证日期字段是不是是准确的范例.在年夜多半情形下,你也必要考证它们的局限,如考证它们是不是是未来或是已往的工夫.假如你利用服务器控件来捕捉一个日期输出值,同时你但愿这个值在一个特定的局限内,你可使用局限考证控件(RangeValidator)并设置它同意的范例为Date范例.这个控件同意你指定一个特别的工夫段经由过程设置肇端的时候.假如你必要以明天的工夫作为参照来考证,好比考证一个工夫是在未来仍是已往,你可使用CustomValidator考证控件.
利用CustomValidator控件来考证一个日期必要设置ControlToValidate和ErrorMessage属性,在OnServerValidate事务中指定一个自界说的考证逻辑办法.上面是示例代码.
<%@PageLanguage="C#"%>
<scriptrunat="server">
voidValidateDateInFuture(objectsource,ServerValidateEventArgsargs)
{
DateTimedt;
//Checkforvaliddateandthatthedateisinthefuture
if((DateTime.TryParse(args.Value,outdt)==false)||
(dt<=DateTime.Today))
{
args.IsValid=false;
}
}
</script>
<html>
<body>
<formid="form1"runat="server">
<div>
<asp:LabelID="Label1"Runat="server"
Text="FutureDate:"></asp:Label>
<asp:TextBoxID="futureDatetxt"Runat="server"></asp:TextBox>
<asp:CustomValidator
ID="CustomValidator1"Runat="server"
ErrorMessage="Invaliddate.Enteradateinthefuture."
ControlToValidate="futureDatetxt"
OnServerValidate="ValidateDateInFuture">
</asp:CustomValidator>
<br/>
<asp:ButtonID="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>标志.
<%@PageLanguage="C#"ValidateRequest="false"%>
<scriptrunat="server">
voidsubmitBtn_Click(objectsender,EventArgse)
{
//Encodethestringinput
StringBuildersb=newStringBuilder(
HttpUtility.HtmlEncode(htmlInputTxt.Text));
//Selectivelyallowand<i>
sb.Replace("<b>","<b>");
sb.Replace("</b>","");
sb.Replace("<i>","<i>");
sb.Replace("</i>","");
Response.Write(sb.ToString());
}
</script>
<html>
<body>
<formid="form1"runat="server">
<div>
<asp:TextBoxID="htmlInputTxt"Runat="server"
TextMode="MultiLine"Width="318px"
Height="168px"></asp:TextBox>
<asp:ButtonID="submitBtn"Runat="server"
Text="Submit"/>
</div>
</form>
</body>
</html>
考证查询字串的值
考证查询字串的长度,局限,格局和范例.一般,你利用一个兼并的正则表达式来完成以下义务:
束缚输出值
设置明白的局限反省前提
指定输出的范例并将它转换成ASP.NET平台下的范例,处置任何由范例转换激发的非常上面的代码示例演示了利用Regex类考证由查询字串传送过去的名字字符串
voidPage_Load(objectsender,EventArgse)
{
if(!System.Text.RegularExpressions.Regex.IsMatch(
Request.QueryString["Name"],@"^{1,40}$"))
Response.Write("Invalidnameparameter");
else
Response.Write("Nameis"+Request.QueryString["Name"]);
}
考证Cookie值
象查询字串如许被保留在Cookie内里的值很简单被用户修正.一样地考证这些值的长度,局限,格局和范例.
考证文件和URL地点
假如你的程序同意输出文件名,文件地点大概文件寄存路径,你必要考证它们的格局是不是准确而且依据你的程序实践情形它指向一个无效的地位.假如此步考证失利,你的程序大概会被毛病地请求会见文件.
考证文件路径
为了不你的程序被用户使用来会见文件,避免承受用户编写代码输出的文件大概文件路径.比方:
假如你承受输出文件名,利用System.IO.Path.GetFileName办法来获得文件的全称
假如你不能不承受输出文件路径,利用System.IO.Path.GetFullPath来获得完全的文件路径
利用MapPath办法避免跨使用程序的映照
假如你利用MapPath办法在服务器上映照一个供应的假造目次到一个物理目次,利用Request.MapPath办法的一个带bool参数的重载版原本避免跨使用程序的映照.上面是此项手艺的示例代码:
try
{
stringmappedPath=Request.MapPath(inputPath.Text,
Request.ApplicationPath,false);
}
catch(HttpException)
{
//Cross-applicationmappingattempted
}
终极的false参数将会避免跨使用程序的映照.这意味着用户不同意利用".."如许的语法供应一个不在你所指定的假造目次内里的不法路径.
假如你利用服务器控件,你可使用Control.MapPathSecure办法猎取假造目次对应的实践目次地点.
Control.MapPathSecure办法在会见一个非受权的文件时抛出一个HttpException的非常.必要更多信息,请参看.NETFramework文档中的Control.MapPathSecure办法先容.
利用代码会见平安机制限定文件输出输入
办理员能够经由过程设置程序使它的可托度为"中"来限定程序向它地点的假造目次读写文件的才能..NET代码平安机制能够包管程序在它地点的假造目次以外没有任何的文件会见权力.
要设置一个使用程序的信托度为"中",能够在Web.config大概Machine.config文件中到场:
<trustlevel="Medium"/>
考证URL
你能够用象上面的如许的正则表达式来对URL举行特性婚配.
^(?:http|https|ftp)://+(?::d{1,5})?(?:|%u{4}|%{2})*$
这只是束缚输出的格局,不考证它是不是在使用程序可承受的局限内.你应当考证它是不是在你的程序的高低文中无效.比方,您的使用程序是不是跟你指定的服务器举行通信?
第三步.对不平安代码举行编码
假如您输出文本输出到一个网页,利用HttpUtility.HtmlEncode办法对它举行编码.假如这些文来自于用户输出,数据库大概一个当地文件,请确保老是如许做.
一样地,假如您誊写的URL内里包括不平安的字符由于他们来自于用户输出内容,数据库等,利用HttpUtility.UrlEncode办法举行编码.
为了避免存储数据前编码大概会使存储的数据遭到损坏,请确保在将它们显现出来时尽量前面的步骤将它们编码.
利用HtmlEncode对不平安的输入编码
HtmlEncode对HTML标志置换成特别含文的字符串来暗示这些标记而又让扫瞄器不把它们看成HTML标志来注释处置.好比."<"被置换成<"(冒号)被交换成"这些标志被显现成有害的文本.
<%@PageLanguage="C#"ValidateRequest="false"%>
<scriptrunat="server">
voidsubmitBtn_Click(objectsender,EventArgse)
{
Response.Write(HttpUtility.HtmlEncode(inputTxt.Text));
}
</script>
<htmlxmlns="http://www.w3.org/1999/xhtml">
<body>
<formid="form1"runat="server">
<div>
<asp:TextBoxID="inputTxt"Runat="server"
TextMode="MultiLine"Width="382px"Height="152px">
</asp:TextBox>
<asp:ButtonID="submitBtn"Runat="server"Text="Submit"
/>
</div>
</form>
</body>
</html>
检察HTML编码的效果,请创建一个假造目次将前述的文件放出来,运转此页面,在文本框中输出一些HTML代码,点击提交按钮.比方,上面的输出被看成一般文原本显现.
Runscriptandsayhello<script>alert(hello);</script>
假如你移除挪用HtmlEncode办法,复杂地输出文本的内容,扫瞄器会实行代码并弹出一个提醒框.
利用UrlEncode办法对不平安的URL地点举行编码
假如你必要猎取有效户输出部分的URL参数,这大概带来必定的平安风险,利用HttpUtility.UrlEncode办法对这个地点字符串编码.
HttpUtility.UrlEncode(urlString);
第四步.对SQL语句利用命令参数体例.
为了不注进式打击请利用SQL的参数体例.参数(Parameters)汇合供应范例检测和长度检测.假如你利用参数汇合,输出的内容将被看成文本值来看待,数据库不会实行包括在个中的代码.利用参数集体例的一个分外的优点是,你能够严厉限制输出的范例和长度.假如输出型超越局限将会触发非常.
当挪用一个存储历程时利用参数集
上面的代码片断演示了在挪用存储历程时利用参数集的例子.
SqlDataAdaptermyCommand=newSqlDataAdapter("AuthorLogin",
myConnection);
myCommand.SelectCommand.CommandType=CommandType.StoredProcedure;
SqlParameterparm=myCommand.SelectCommand.Parameters.Add(
"@LoginId",SqlDbType.VarChar,11);
parm.Value=Login.Text;
在创立你本人的SQL语句时利用参数集.
假如你不克不及利用存储历程,你仍旧可使用参数集,请看上面的代码.
SqlDataAdaptermyCommand=newSqlDataAdapter(
"SELECTau_lname,au_fnameFROMAuthorsWHEREau_id=@au_id",myConnection);
SQLParameterparm=myCommand.SelectCommand.Parameters.Add(
"@au_id",SqlDbType.VarChar,11);
Parm.Value=Login.Text;
假如必要猎取更多的假如避免SQL注进打击的信息请参看Howto:ProtectFromSQLInjectioninASP.NET
第五步.考证ASP.NET的毛病信息没有被前往到客户端
你可使用<customErrors>元从来设置客户端,一样平常的毛病信息应当被程序毛病检测机制前往到客户端.
请确认已变动web.config中的mode属性为"remoteOnly",上面是示例.
<customErrorsmode="remoteOnly">
何在装了一个ASP.NET的程序以后,你能够依照以下设定指定客户真个毛病信息页面。
<customErrorsmode="on"defaultRedirect="YourErrorPage.htm">
分外的资本,请检察相干主题内容:
在ASP.NET中怎样利用正则表达式束缚输出.
避免SQL注进打击
避免跨站剧本打击
PS:终究翻完了啊,真累,花了快要三天的工夫,实在看看这些句子都很复杂的。我第一次做翻译,译得欠好的话请人人多多包容,感谢。
归根到底,Java跨平台可以,但是要重新编写代码,否则还分什么J2EE/J2SE/J2ME呢! ASP.NET:ASP.net是Microsoft.net的一部分,作为战略产品,不仅仅是ActiveServerPage(ASP)的下一个版本;它还提供了一个统一的Web开发模型,其中包括开发人员生成企业级Web应用程序所需的各种服务。ASP.NET的语法在很大程度上与ASP兼容,同时它还提供一种新的编程模型和结构,可生成伸缩性和稳定性更好的应用程序,并提供更好的安全保护。 在调试JSP代码时,如果程序出错,JSP服务器会返回出错信息,并在浏览器中显示。这时,由于JSP是先被转换成Servlet后再运行的,所以,浏览器中所显示的代码出错的行数并不是JSP源代码的行数。 ASP.net的速度是ASP不能比拟的。ASP.net是编译语言,所以,当第一次加载的时候,它会把所有的程序进行编译(其中包括worker进程,还有对语法进行编译,形成一个程序集),当程序编译后,执行速度几乎为0。 可以看作是VC和Java的混合体吧,尽管MS自己讲C#内核中更多的象VC,但实际上我还是认为它和Java更象一些吧。首先它是面向对象的编程语言,而不是一种脚本,所以它具有面向对象编程语言的一切特性。 JSP/Servlet虽然在国内目前的应用并不广泛,但是其前途不可限量。 虽然在形式上JSP和ASP或PHP看上去很相似——都可以被内嵌在HTML代码中。但是,它的执行方式和ASP或PHP完全不同。在JSP被执行的时候,JSP文件被JSP解释器(JSPParser)转换成Servlet代码,然后Servlet代码被Java编译器编译成.class字节文件,这样就由生成的Servlet来对客户端应答。所以,JSP可以看做是Servlet的脚本语言(ScriptLanguage)版。 ASP.net的速度是ASP不能比拟的。ASP.net是编译语言,所以,当第一次加载的时候,它会把所有的程序进行编译(其中包括worker进程,还有对语法进行编译,形成一个程序集),当程序编译后,执行速度几乎为0。 碰到复杂点的问题都不知道能不能解决,现在有点实力的公司都选择自已在开源的基础上做开发。但没听说过有人在IIS上做改进的,windows、sqlserver集群方面的应用也很少见。
页:
[1]