Web安全及XSS(一)

Web安全

web1.0: 更多关注服务器动态脚本安全问题,将可执行脚本webshell上传到服务器上获得权限。PHP至今只能靠代码规范约束防止漏洞,无法语言本身杜绝。
web安全里程碑事件:SQL注入, XSS
web2.0 XSS,CSRF攻击更强大,从服务器端转向了客户端,转向浏览器

安全问题的本质:信任问题。安全方案设计的基础也是建立在信任基础上。
安全是个持续的过程。
安全三要素: 机密性(如加密),完整性(如数字签名)和可用性(拒绝服务攻击DOS)。

互联网安全的核心问题,是数据安全的问题

安全法则
  • Secure by default
  1. 白名单(web白名单)
  2. 最小权限原则,系统只授予主题必要的权限
  • 纵深防御
  1. 不同角度和层面对系统做出解决方案,共同组成整个防御体系
  2. 在正确的地方做正确的事
  • XSS Defense 技术的发展过程
    过滤输入中的特殊符号 => 区分富文本和非富文本 =>对富文本开始做语法树分析 => 综合方案

  • 数据和代码分离原则:
    注入引起的问题,大都因为数据和代码没有分离。
    如XSS,是HTML或JS注入产生的。

  • 不可预测性原则
    (从克服攻击方法的角度看问题)

同源策略

浏览器是互联网重要入口,安全攻防中,浏览器是其中最重要的一部分。浏览器安全以同源策略为基础。

同源指: host(域名或者ip地址),子域名,端口,协议一致。

跨域标签 <script> <img> <iframe> <link>可跨域加载资源,不受同源策略限制。浏览器限制了Js的权限,不能读写返回的内容。
同源策略限制的有: DOM,Cookie,XMLHttpRequest,浏览器加载的一些第三方插件也有各自的同源策略。
Flash通过目标网站提供的crossdomain.xml判断是否允许Flash跨域访问,里面
设置可跨的域等。

浏览器的同源策略也会被绕过,例如IE8的CSS跨域漏洞。

恶意网址拦截

浏览器周期性从服务端获取一份最新的恶意网址黑名单,用户访问时会弹出警告。
挂马网站(有恶意脚本如Javascript, Flash,植入木马);钓鱼网站(模仿知名网站相似页面欺骗用户)
(PhishTank是互联网免费提供的恶意网址黑名单组织之一;Google SafeBrowsing API;EV SSL证书。)

浏览器的一些安全措施

1.IE8 XSS Filter,对抗反射型XSS. 当访问的URL中包含xss攻击的脚本时,IE修改其中的关键字使攻击失败(正则);
2. Firefox 4推出Content Security Policy(CSP).做法是服务器端返回一个HTTP头,并在其中描述页面应该遵守的安全策略。

  • 在没有第三方插件帮助的情况下,XSS无法控制HTTP头
  • policy描述灵活,比如可以设置信任的域名,图片来源,脚本来源等。eg: allow 'self' *.mydomain.com; img-src *;
  • 设计理念出色,但配置规则复杂,页面较多时很难一个个配置,且维护成本大

攻击一:跨站脚本攻击(XSS)Cross Site Script

HTML注入篡改网页。分为三种形式:

  • 反射型XSS.

用户输入的数据反射给浏览器,往往需要诱使用户“点击”一个恶意链接,才能攻击成功。也叫“非持久型XSS”(No-persistent XSS).

  • 存储型XSS

存储型XSS会把用户输入的数据“存储”在服务器端。常见场景:黑客写一篇含有恶意JS代码的文章,所有访问该文章的用户,会在她们的浏览器中执行该恶意JS。黑客把恶意的脚本保存在服务器端,也叫做“持久型XSS”(Persistent XSS)。

  • DOM Based XSS

效果类似反射型XSS,但是形成原因较特别。通过修改页面的DOM节点形成。

XSS Payload(恶意脚本)攻击重点
  1. 最常见 XSS payload,就是读取浏览器Cookie对象,发起“Cookie劫持”攻击。Cookie一般是用户登陆的凭证。(HttpOnly可防止)
    cookie攻击常见方式: TODO

  2. 构造GET与POST请求
    例如:
    插入图片发起get请求

    var img = document.createElement('img')
    img.src = 'http://blog.sohu.com/.../entry.do?m=delete&id=1234556';
    document.body.appendChild(img)
    

    构造form表单自动提交post请求,或通过XMLHttpRequest发送post请求。

  3. XSS钓鱼
    模拟相似网站获取用户名密码

  4. 识别用户浏览器(通过知道用户使用的浏览器 操作系统,又可能实施精准的浏览器内存攻击,最终给用户电脑植入木马)

  5. 识别用户安装的软件
    判断用户安装的软件,选择相应的浏览器漏洞,达到植入木马的目的。一些三方软件也可能会泄漏一些信息。

  6. CSS History Hack
    通过CSS发现用户曾将访问过的网站,style的visited属性。

  7. 识别用户IP

  8. XSS Worm
    XSS worm是XSS的一种终极利用方式,破坏力和影响力巨大。
    但是发起此攻击有一定条件: 一般来说,用户之间发生交互行为的页面,如果存在存储型XSS,则比较容易发生XSS Worm攻击。 如用户留言,发送站内信等页面均是XSS Worm高发区。

XSS构造方式
  1. 利用字符编码
  2. 绕过长度限制
  • 服务端限制-利用Event缩短字节数
    html: <input type="text" value="$var">
    $var:">scrip>alert(/XSS)</script>"
    $var:改成: "alert(1) //"
  • 或者将代码藏在location.hash中。根据HTTP协议,location.hash不会在HTTP包中发送。
    $var :" eval(location.hash.substr(1))"
    Url构造为:http://www.a.com/test.html#alert(1)
    location.hash本身没有长度限制,但是浏览器地址长度有限制,所以也可以加载远程JS写更多代码
  • 某些情况下利用注释写入更多字节。
    <input id=1 type="text" value="" /><!--" "/> xxxxxx <input id=2 type="text" value=""--><script>alert(/xss);</script>" />
  1. 使用<base>标签
    base标签指定其后的标签默认从base url取url, 可以出现在页面的任何地方。攻击者如果在页面中插入<base>标签,就可以在远程服务器上伪造图片,链接或脚本,劫持当前页面中所有使用“相对路径”标签。
    在设计XSS安全方案时,一定要过滤掉这个非常危险的标签。
<base href="http"//www.evil.com" />
// ...
<script src="x.js"></script>

4.window.name
window对象不受同源策略限制,攻击者可以利用该对象,实现跨域跨页面传递数据。
a页面:

<script>
 window.name = 'test';
  alert(document.domain + window.name);
   window.location = './b.html';
</script>

b页面:

<script>
alert(document.domain + window.name);
</script>

window.name从a页面传到b页面。
实际在攻击时,很可能是这样的:

<script>
window.name = "alert(document.cookie)";
location.href="http://xxxx/xssed.php";
</script>

在同一窗口打开XSS的站点之后,只需通过XSS执行一下代码即可eval(name)

  1. Mission Impossible
    存储型XSS对攻击者用处比反射型要大,因为存储型XSS在用户访问正常URL时自动触发;反射型XSS会修改正常URL,要求攻击者将XSS url发送给用户点击
  • apache Expected Header XSS, 服务器出错返回时,会把Expected头的内容未经任何处理写入页面中,Expect头中的HTML代码就被浏览器解析执行。在HTTP头无法被更改的时候属于鸡肋,但是Flash构造请求的时候可以修改HTTP头。

  • 回旋镖-将要利用的反射型XSS嵌入存储型XSS中。

    浏览器同源策略,A域上的XSS很难影响到B域上的用户。、
    如果B域存在一个反射型XSS_B,A域存在存储型XSS_A,用户访问A域上的XSS_A,嵌入B域XSS_B,达到攻击B域的目的。先在XSS_A上写一个form,自动提交到XSS_B,在XSS_B中再跳回XSS_A.

  1. Flash XSS
    Flash中可以嵌入ActionScript脚本的,ActionScript是强大灵活的脚本,可以用它发起网络连接,应尽可能禁止用户上传或加载自定义Flash文件。

XSS Filter应禁用<embed> <object>等标签;
如果要用Flash,视频要求转码称’flv’文件;如果是动态脚本的flash,需要配置flash参数。

  1. Js开发框架漏洞
    YUI:
    History Manager功能中有这样的问题,点击一个tab页,页面加载完成之后,在URL的hash中插入恶意脚本。因为history.js的_updatelframe方法中信任了用户可控制的变量,最后被写入页面导致脚本执行。
    修补: htmlEscape

    Jquery:
    本身出现的XSS漏洞很少,但是它只是对JS语言的封装,并不能解决代码逻辑上产生的问题。
    html()方法,参数写入DOM节点的innerHTML,可能产生“DOM Based XSS”.eg.$('div.demo-container').html("<img src=# {alert(1)} />");

    框架并不能让开发者高枕无忧,同样会产生安全问题。除了关注框架本身安全之外,还要提高安全意识,理解并正确使用开发框架。

XSS防御策略
  1. 浏览器内置一些对抗XSS的措施,如Firefox的CSP.(Chrome safari等均可用,IE貌似不可用)
  2. HttpOnly,解决XSS之后的Cookie劫持,微软提出,IE6实现,禁止Js读写Cookie. 可设置关键cookie为HttpOnly,但不万能,也不能解决除窃取用户信息,模拟用户身份执行操作等非cookie劫持的问题。
  3. 输入检查 XSS-Filter
    如XSS, SQL 注入等,均会要求攻击者构造一些特殊字符,所以需要检查,类似设置白名单。最好在客户端和服务器端均检查,服务端检查是必要的。
    一般检查用户输入的数据是否包含<, >, ', ",<script>, " javascript"等。

缺点:

  1. 无法根据用户输出语境,可能会漏报,比如用户提交的恶意url,url是合法数据;
  2. <等字符处理可能会改变用户数据语义, eg1+1<3
  3. 对敏感字符转义结果不是用户想看到的
  1. 输出检查—除去富文本的输出外,在变量输出到HTML页面时,可以使用编码或者转义方式防御XSS攻击
  1. 安全的编码函数: htmlEncode(), PHP的htmlentities(), htmlspecialchars(), JavascriptEncode()等,以及url中的encodeURIComponent()
encodeURIComponent('><script>console.log(document.cookie)</script>')
// '%3E%3Cscript%3Econsole.log(document.cookie)%3C%2Fscript%3E'
具体防御:

XSS本质是“HTML注入”,根治XSS,可以列出所有XSS发生的场景一一解决。

  1. html标签中输出:
    场景:

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

    构造方式<script>or 任何产生脚本执行方式
    攻击实现:

    <div><script>alert(/xss)</script></div> 
    // or
    <a href=# ><img src=# alert(1) /></a>
    

    防御:对变量HtmlEncode

  2. html属性中输出
    场景:

    <div name="$var "></div>
    

    构造方式:与html标签中一样
    攻击实现:

    <div name=" "><script>alert(/xss/)</script></div>
    

    防御: HtmlEncode

  3. <script>标签中输出
    场景:

    <script>
    var x = '$var';
    </script>
    

    构造方式:闭合引号
    攻击实现:

    <script>
    var x = '';alert(/xss);//;
    </script>
    

    防御: javascriptEncode

  4. 事件中输出
    场景:

    <a href# "funcA('$var')" >test</a>
    

    攻击实现:

     <a href# "funcA(' ');alert(/xss/);//" >test</a>
    

    防御:JavascriptEncode

  5. css输出
    尽可能禁止用户可控制的变量在’ <style>标签’, HTML的style属性, CSS文件中输出。如果一定这样,可以使用对css编码的函数。

  6. 地址中输出
    场景:

    <a href="http://xxx.com/?test=$var" >test</a>
    // or
    <a href="$var" >test<a>
    

    攻击实现:

    <a href="http://xxx.com/?test= " alert(1)"" >test</a>
    // or
    <a href="javascript:alert(1);" >test<a>
    

    防御: 用encodeURIComponent等编码函数对URl编码。

  7. 处理富文本
    有时候,网站需要允许用户提交一些自定义的HTML代码,称为“富文本”。如何区分“富文本”和XSS?
    输入检查, HTML是结构化语言,比较好分析。
    防御:
    htmlparser解析HTML代码标签,标签属性和事件;严格禁止事件,以及<iframe> <script> <base> <form>等危险标签也应该严格禁止。
    在标签/属性/事件的选择上,应该使用白名单,避免使用黑名单。
    富文本过滤中,允许用户自定义CSS, style,也可能会导致XSS攻击,最好尽可能禁止用户自定义css和style.如果一定要用户自定义样式,则只能像过滤“富文本”一样过滤CSS,可以使用CSS Parser对样式智能分析。

  8. 处理DOM based XSS
    DOM Based XSS是从Javascript中输出数据到HTML页面中,前文提到的XSS均是针对从服务器应用直接输出到HTML页面,因而前面的方法不适用于DOM Based XSS.
    场景:

    <script>
    var x='$var';
    document.write("<a href='"+x+"' >test</a>");
    </script>	
    

    假设为了保护$var直接在 <script>中产生XSS,服务端对其进行javascriptEscape. 可是$var在document.write时,仍然会产生XSS,因为对x进行了解码。
    防御:
    $var输出到<script>中时,应执行一次javascriptEncode;其次,在document.write输出到HTML页面时,若输出到事件或者脚本,则要做一次javascriptEncode,输出到HTML内容或属性,要做一次HtmlEncode.

    Javascript输出到HTML页面,相当于一次XSS输出的过程, 需要分语境使用不同编码函数。

    触发DOM Based XSS的地方有很多,以下是Js输出到HTML页面必经之路
    document.write(); document.writeIn(); xxx.innerHTML =; xxx.outHTML =; innerHTML.replace ;document.attachEvent(); window.attachEvent() ;document.location.replace(); document.location.assign()…

    除了服务器端直接输出变量到JavaScript外,还有以下几个地方可能会成为DOM Based XSS输入点,也需要重点关注。

    页面中所有inputs框; window.location(href, hash等); window.name; document.referrer; document.cookie; localStorage; XMLHttpRequest返回的数据

总结:

XSS漏洞虽然复杂,却是可以彻底解决,需要深入XSS攻击原理,针对不同场景使用不同的方法。

注: 基于《白帽子讲web安全》, 文章中的一些编码方法可能较老,可以自己查找更新的方式。

扩展阅读:
https://excess-xss.com/
https://juejin.im/post/5bad9140e51d450e935c6d64#heading-31
https://github.com/showdownjs/showdown/wiki/Markdown’s-XSS-Vulnerability-(and-how-to-mitigate-it)
(markdown也有做安全过滤,尝试a href中加载javascript,直接过滤掉了href属性)
React注入: https://zhuanlan.zhihu.com/p/28434174

猜你喜欢

转载自blog.csdn.net/u011141492/article/details/89164637