|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
刚刚打开这篇专题,猛然见到HAL9000发表的《对于大型公司项目平台选择j2ee的几层认识》系列,深受启发。成绩所处情况:IIS7.5,ASP.NET4.0,使用程序池(ApplicationPool)运转于集成形式(Integrated)。
明天一名园友向我们反应用网摘保藏博客文章LINQ那些事(9)-剖析Table<T>.Attach激发的非常息争决办法时堕落(注重:文章题目中有尖括号)。
我们查了一下,详细的毛病信息是:ApotentiallydangerousRequest.QueryStringvaluewasdetectedfromtheclient(t="...9)-剖析Table<T>.Attach激发的非常息争决办法..."). 毛病信息剖析:为了避免XSS跨站剧本打击,IIS的默许平安设置不同意查询字符串中包括尖括号,而此次网摘保藏操纵却违背了这个划定,因而激发了这个毛病。
关于这个成绩,你大概会说这么复杂的成绩也美意思写篇博客,一定是经由过程url参数传送题目时没有编码。假如真是如许,也会写篇博客,但不是手艺分享,而是检查书。
刚入手下手看到这个毛病时,切实其实闪过如许的动机——岂非真的忘了编码?。。。不会的,记得编了。翻开代码一看,松了一口吻,检查书不必写了,但手艺分享必需的,固然条件是办理了成绩。
上彀摘顶用到的js代码:- varurl=http://home.cnblogs.com/wz/create?t=+encodeURIComponent(document.title);
复制代码 看!方才的!encodeURIComponent,经由有数次理论证实过的无效的JavascriptUrlEncode体例。
但是,如今居然出成绩了。。。
起首嫌疑是否是页面题目中没有对题目内容举行HTML编码。反省确认,编码了:- <title>LINQ那些事(9)-剖析Table<T>.Attach激发的非常息争决办法-海南K.K-博客园</title>
复制代码 接着,看一下document.title的值:- LINQ那些事(9)-剖析Table<T>.Attach激发的非常息争决办法-海南K.K-博客园
复制代码 居然主动举行HTML解码了!这仍是第一次发明!解码也不妨啊,encodeURIComponent对尖括号也会编码。
持续行进,看一下encodeURIComponent(document.title)的值:- LINQ%E9%82%A3%E4%BA%9B%E4%BA%8B(9)-%E8%A7%A3%E6%9E%90Table%3CT%3E.Attach%E5%BC%95%E5%8F%91%E7%9A%84%E5%BC%82%E5%B8%B8%E5%92%8C%E8%A7%A3%E5%86%B3%E6%96%B9%E6%B3%95%20-%20%E6%B5%B7%E5%8D%97K.K%20-%20%E5%8D%9A%E5%AE%A2%E5%9B%AD
复制代码 <被编码为%3C,>被编码为%3E,一般啊。明显是编了码的尖括号,IIS怎样会报错呢?岂非扫瞄器偷偷解了码,再发送给IIS。
特此反省了一下扫瞄器哀求的URL,扫瞄器对编了码的URL涓滴未动。
岂非是IIS惹的祸?看一下IIS日记中纪录的URL:
日记纪录申明了IIS收到的也是编过码的尖括号。岂非祸首罪魁是IIS!
也就是说IIS在判别时,先将查询字符串举行解码,将%3C解码为<,将%3E解码>,然后发明有尖括号,然后堕落!
是否是如许呢?不进虎穴,焉得原形。依据毛病信息,用ILSPY检察HttpRequest的源代码。
毛病信息以下:
用ILSPY一起追踪:
1.HttpRequest.QueryString- publicNameValueCollectionQueryString{get{if(this._queryString==null){this._queryString=newHttpValueCollection();if(this._wr!=null){this.FillInQueryStringCollection();}this._queryString.MakeReadOnly();}if(this._flags[1]){this._flags.Clear(1);HttpRequest.ValidateNameValueCollection(this._queryString,"Request.QueryString");}returnthis._queryString;}}
复制代码 2.FillInQueryStringCollection()- //System.Web.HttpRequestprivatevoidFillInQueryStringCollection(){byte[]queryStringBytes=this.QueryStringBytes;if(queryStringBytes!=null){if(queryStringBytes.Length!=0){this._queryString.FillFromEncodedBytes(queryStringBytes,this.QueryStringEncoding);return;}}else{if(!string.IsNullOrEmpty(this.QueryStringText)){this._queryString.FillFromString(this.QueryStringText,true,this.QueryStringEncoding);}}}
复制代码 3.FillFromEncodedBytes- //System.Web.HttpValueCollectioninternalvoidFillFromEncodedBytes(byte[]bytes,Encodingencoding){intnum=(bytes!=null)?bytes.Length:0;for(inti=0;i<num;i++){this.ThrowIfMaxHttpCollectionKeysExceeded();intnum2=i;intnum3=-1;while(i<num){byteb=bytes[i];if(b==61){if(num3<0){num3=i;}}else{if(b==38){break;}}i++;}stringname;stringvalue;if(num3>=0){name=HttpUtility.UrlDecode(bytes,num2,num3-num2,encoding);value=HttpUtility.UrlDecode(bytes,num3+1,i-num3-1,encoding);}else{name=null;value=HttpUtility.UrlDecode(bytes,num2,i-num2,encoding);}base.Add(name,value);if(i==num-1&&bytes[i]==38){base.Add(null,string.Empty);}}}
复制代码 就是在这里举行解码的,挪用的就是HttpUtility.UrlDecode。
本来祸首祸不是IIS,是ASP.NET!
成绩缘故原由小结:
ASP.NET在检测XSS跨站剧本打击时,会将查询字符串解码,然后挪用System.Web.CrossSiteScriptingValidation.IsDangerousString()举行反省。以是任何对查询字符串中的尖括号举行间接的UrlEncode编码操纵(好比Javascript的encodeURIComponent,escape,encodeURI)都没法逃过ASP.NET的反省。
那没有办理办法呢?有!我们找到了,而且已在实践中利用,不信的话,能够用网摘保藏一下LINQ那些事(9)-剖析Table<T>.Attach激发的非常息争决办法。
办理办法:
1.经由过程上面的代码猎取原装的未举行过HTML解码的页面题目(Javascript代码),这里<酿成了<,>酿成了>:- vartitle=document.getElementsByTagName(title)[0].innerHTML;
复制代码 (注重:后面已提过,document.title会对<title></title>中的内容主动举行HTML解码,以是不要用它。)
2.然后经由过程Javscript的encodeURIComponent进一步编码,如许能够躲过ASP.NET的XSS跨站剧本打击反省(反省时,ASP.NET失掉的是<与>)。
3.在ASP.NET程序中猎取这个查询字符串时,必要举行分外的HtmlDecode操纵,C#代码以下:- HttpUtility.HtmlDecode(Request.QueryString["t"]);
复制代码 感言
办理一个成绩,最好的庆贺体例就是写一篇博客!不但能够分享给他人,本人还会有分外的劳绩!并且必定会有!
原本写这篇博客时,我用的题目是“[Javascript]document.title引发的HtmlDecode成绩”,事先觉得是Javascript的成绩,写博客过程当中才发明是ASP.NET的成绩。由于在写博客过程当中,你要分明地表达出来,来不得半点纰漏,你会对成绩举行更深切的研讨。
一个工具,你想分明了,其实不代表你真正了解。只要你分明地表达出来,让他人能分明,才申明你真正了解。
前几天同学问我学习方向的问题。有点想法,不知道对不对,怕误导同学,现在“开源一下”。注:括号内是我现在整理的时填加上的。 |
|