您的位置:首页 > 其它

web安全————XSS(预防篇)

2016-12-01 10:47 375 查看
     现在市面浏览器都对XSS做了一些防范措施,如firefox的CSP、Noscrip扩展和IE8内置的XSS Filter等等。但是对于一个站点来说,这往往是不够的,还需要做出更优秀更好的方案防止XSS攻击。如httponly、输入检查、输出检查等等。

     httponly是由微软提出来的,目前很多浏览器都支持该功能。带有httponly标识将禁止javascript访问cookie。通常情况下httponly是在服务端返回set-cookie时标记:

     Set-Cookie: <name>=<value>[; <Max-Age>=<age>]

     [; expires=<date>][; domain=<domain_name>]

     [; path=<some_path>][; secure][; HttpOnly]

     有时候服务器可能会设置多个cookie,这时httponly可以选择性的加在任何有必要的关键cookie值上:

     <?php

     header("Set-Cookie: cookie1=test1;");

     header("Set-Cookie: cookie2=test2;httponly", 

     false);

     ?>

     <script>

       alert(document.cookie);

     </script>

     这样javascript能读取到cookie1却不能读取cookie2。

     附不同语言中cookie添加httponly代码:

     java EE:

     response.setHeader("Set-Cookie", 

     "cookiename=value;  

     Path=/;Domain=domainvalue;Max-Ag

     e=seconds;HTTPOnly");

     C#

     HttpCookie myCookie = new 

     HttpCookie("myCookie");

     myCookie.HttpOnly = true;

     Response.AppendCookie(myCookie);     

     VB.NET

     Dim myCookie As HttpCookie = new 

     HttpCookie("myCookie")

     myCookie.HttpOnly = True

     Response.AppendCookie(myCookie)

     PHP4

     header("Set-Cookie: hidden=value; httpOnly");

     PHP5

     setcookie("abc", "test", NULL, NULL, NULL, 

     NULL, TRUE); //最后一个参数为httponly属性。

     输入检查

     一般情况下,常见的web漏洞例如XSS、SQL injection等在构造攻击代码时都含有一些特殊字符,而这些字符可能是正常用户不会用到的,那么输入检查在一定程度上提高了攻击门槛。

     输入检查的逻辑必须是在服务端中实现,在客户端使用javascript进行检查是很容易就被攻击者绕过。目前很多web开发普遍做法是同时在服务端代码与客户端javascript中实现输入检查。其实输入检查还是存在很多问题,比如攻击者可以将攻击代码放在远端,在用户浏览器插入正常URL,URL一般不会包含特殊字符,同样也可实施XSS攻击。

     输入检查

     既然输入检查存在问题,那么输出检查呢???

     一般来说,输了富文本的输出外,在变量输出到HTML页面时可以使用编码方式或转义方式来防御XSS攻击。常见的HTMLEncode中转换如下字符:

     & --> &

     < --> <

     > --> >

     " --> "

     ' --> '   ' 不推荐

     / --> /   包含反斜线是因为它可能会闭合一些HTML entity

     PHP中htmlentities()和htmlspe-cialchars()两个函数可以满足安全要求

     JavaScript的编码方式可以使用JavascriptEncode

     下面对比一下:

     var x = escapeJavascript($evil);

     var y = '"'+escapeJavascript($evil)+'"';

     第二行进行了转义,那么两行代码输出结果为:

     var x = 1;alert(2);

     var y = "1;alert(2)";

     第一行执行额外代码,第二行则是安全的,那么对于后者来说,攻击者需要逃逸出引号的范围,显然攻击门槛又提高了。出去转义外,还可以使用十六进制“\xHH”的方式进行编码:

     var x = 1;alert(2);使用十六进制编码后:var x = 1\x3balert\x282\x29;这样就安全很多。

     如何正确的防御XSS攻击??

     为了更好的设计防御XSS攻击方案,需要认清XSS产生的本质原因。XSS的本质还是一种“HTML注入”,即是用户的数据被当成HTML代码一部分来执行,从而混淆了原本的语义。例如:

     <div>$var</div>

     <a href=# >$var</a>

     在这种场景下,$var表示用户数据,但是输出时未做任何处理,那么XSS攻击者构造一个<script>标签即可让脚步被执行:

     <div><script>alert(/xss/)</script></div>或者<a href=# ><img src=# onerrot=alert(1) /></a>。此时,应该采用HtmlEncode,确保输出的变量在引号中:

     <script>

     var x = "$var";

     </script>

     攻击者的攻击代码需要先闭合引号才能实施XSS攻击:

     <script>

     var x = "";alert(/xss/);//"

     </script>

     同理<a href=# onclick="funcA('$var')" >test</a>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息