Web安全
web1.0: 更多关注服务器动态脚本安全问题,将可执行脚本webshell上传到服务器上获得权限。PHP至今只能靠代码规范约束防止漏洞,无法语言本身杜绝。
web安全里程碑事件:SQL注入, XSS
web2.0 XSS,CSRF攻击更强大,从服务器端转向了客户端,转向浏览器
安全问题的本质:信任问题。安全方案设计的基础也是建立在信任基础上。
安全是个持续的过程。
安全三要素: 机密性(如加密),完整性(如数字签名)和可用性(拒绝服务攻击DOS)。
互联网安全的核心问题,是数据安全的问题。
安全法则
- Secure by default
- 白名单(web白名单)
- 最小权限原则,系统只授予主题必要的权限
- 纵深防御
- 不同角度和层面对系统做出解决方案,共同组成整个防御体系
- 在正确的地方做正确的事
-
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(恶意脚本)攻击重点
-
最常见 XSS payload,就是读取浏览器Cookie对象,发起“Cookie劫持”攻击。Cookie一般是用户登陆的凭证。(HttpOnly可防止)
cookie攻击常见方式: TODO -
构造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请求。
-
XSS钓鱼
模拟相似网站获取用户名密码 -
识别用户浏览器(通过知道用户使用的浏览器 操作系统,又可能实施精准的浏览器内存攻击,最终给用户电脑植入木马)
-
识别用户安装的软件
判断用户安装的软件,选择相应的浏览器漏洞,达到植入木马的目的。一些三方软件也可能会泄漏一些信息。 -
CSS History Hack
通过CSS发现用户曾将访问过的网站,style的visited属性。 -
识别用户IP
-
XSS Worm
XSS worm是XSS的一种终极利用方式,破坏力和影响力巨大。
但是发起此攻击有一定条件: 一般来说,用户之间发生交互行为的页面,如果存在存储型XSS,则比较容易发生XSS Worm攻击。 如用户留言,发送站内信等页面均是XSS Worm高发区。
XSS构造方式
- 利用字符编码
- 绕过长度限制
- 服务端限制-利用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>" />
- 使用
<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)
- 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.
- Flash XSS
Flash中可以嵌入ActionScript脚本的,ActionScript是强大灵活的脚本,可以用它发起网络连接,应尽可能禁止用户上传或加载自定义Flash文件。
XSS Filter应禁用
<embed> <object>
等标签;
如果要用Flash,视频要求转码称’flv’文件;如果是动态脚本的flash,需要配置flash参数。
-
Js开发框架漏洞
YUI:
History Manager功能中有这样的问题,点击一个tab页,页面加载完成之后,在URL的hash中插入恶意脚本。因为history.js的_updatelframe方法中信任了用户可控制的变量,最后被写入页面导致脚本执行。
修补: htmlEscapeJquery:
本身出现的XSS漏洞很少,但是它只是对JS语言的封装,并不能解决代码逻辑上产生的问题。
html()方法,参数写入DOM节点的innerHTML,可能产生“DOM Based XSS”.eg.$('div.demo-container').html("<img src=# {alert(1)} />");
框架并不能让开发者高枕无忧,同样会产生安全问题。除了关注框架本身安全之外,还要提高安全意识,理解并正确使用开发框架。
XSS防御策略
- 浏览器内置一些对抗XSS的措施,如Firefox的CSP.(Chrome safari等均可用,IE貌似不可用)
- HttpOnly,解决XSS之后的Cookie劫持,微软提出,IE6实现,禁止Js读写Cookie. 可设置关键cookie为HttpOnly,但不万能,也不能解决除窃取用户信息,模拟用户身份执行操作等非cookie劫持的问题。
- 输入检查 XSS-Filter
如XSS, SQL 注入等,均会要求攻击者构造一些特殊字符,所以需要检查,类似设置白名单。最好在客户端和服务器端均检查,服务端检查是必要的。
一般检查用户输入的数据是否包含<, >, ', ",<script>, " javascript"
等。
缺点:
- 无法根据用户输出语境,可能会漏报,比如用户提交的恶意url,url是合法数据;
- 对
<
等字符处理可能会改变用户数据语义, eg1+1<3
- 对敏感字符转义结果不是用户想看到的
- 输出检查—除去富文本的输出外,在变量输出到HTML页面时,可以使用编码或者转义方式防御XSS攻击
- 安全的编码函数: 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发生的场景一一解决。
-
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
-
html属性中输出
场景:<div name="$var "></div>
构造方式:与html标签中一样
攻击实现:<div name=" "><script>alert(/xss/)</script></div>
防御: HtmlEncode
-
<script>
标签中输出
场景:<script> var x = '$var'; </script>
构造方式:闭合引号
攻击实现:<script> var x = '';alert(/xss);//; </script>
防御: javascriptEncode
-
事件中输出
场景:<a href# "funcA('$var')" >test</a>
攻击实现:
<a href# "funcA(' ');alert(/xss/);//" >test</a>
防御:JavascriptEncode
-
css输出
尽可能禁止用户可控制的变量在’<style>
标签’, HTML的style属性, CSS文件中输出。如果一定这样,可以使用对css编码的函数。 -
地址中输出
场景:<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编码。
-
处理富文本
有时候,网站需要允许用户提交一些自定义的HTML代码,称为“富文本”。如何区分“富文本”和XSS?
输入检查, HTML是结构化语言,比较好分析。
防御:
htmlparser解析HTML代码标签,标签属性和事件;严格禁止事件,以及<iframe> <script> <base> <form>
等危险标签也应该严格禁止。
在标签/属性/事件的选择上,应该使用白名单,避免使用黑名单。
富文本过滤中,允许用户自定义CSS, style,也可能会导致XSS攻击,最好尽可能禁止用户自定义css和style.如果一定要用户自定义样式,则只能像过滤“富文本”一样过滤CSS,可以使用CSS Parser对样式智能分析。 -
处理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