“安全”是个很大的话题,各类安全问题的类型也是种类繁多。若是咱们把安全问题按照所发生的区域来进行分类的话,那么全部发生在后端服务器、应用、服务当中的安全问题就是“后端安全问题”,全部发生在浏览器、单页面应用、Web页面当中的安全问题则算是“前端安全问题”。好比说,SQL注入漏洞发生在后端应用中,是后端安全问题,跨站脚本攻击(XSS)则是前端安全问题,由于它发生在用户的浏览器里。前端
除了从安全问题发生的区域来分类以外,也能够从另外一个维度来判断:针对某个安全问题,团队中的哪一个角色最适合来修复它?是后端开发仍是前端开发? 后端
总的来讲,当咱们下面在谈论“前端安全问题”的时候,咱们说的是发生在浏览器、前端应用当中,或者一般由前端开发工程师来对其进行修复的安全问题。 跨域
按照上面的分类办法,咱们总结出了8大典型的前端安全问题,它们分别是: 浏览器
老生常谈的XSS 安全
警戒iframe带来的风险 服务器
别被点击劫持了 框架
错误的内容推断 ide
防火防盗防猪队友:不安全的第三方依赖包 网站
用了HTTPS也可能掉坑里 编码
本地存储数据泄露
缺失静态资源完整性校验
因为篇幅所限,本篇文章先给各位介绍前4个前端安全问题。
XSS是跨站脚本攻击(Cross-Site Scripting)的简称,它是个老油条了,在OWASP Web Application Top 10排行榜中长期霸榜,从未掉出过前三名。XSS这类安全问题发生的本质缘由在于,浏览器错误的将攻击者提供的用户输入数据当作JavaScript脚本给执行了。
XSS有几种不一样的分类办法,例如按照恶意输入的脚本是否在应用中存储,XSS被划分为“存储型XSS”和“反射型XSS”,若是按照是否和服务器有交互,又能够划分为“Server Side XSS”和“DOM based XSS”。
不管怎么分类,XSS漏洞始终是威胁用户的一个安全隐患。攻击者能够利用XSS漏洞来窃取包括用户身份信息在内的各类敏感信息、修改Web页面以欺骗用户,甚至控制受害者浏览器,或者和其余漏洞结合起来造成蠕虫攻击,等等。总之,关于XSS漏洞的利用,只有想不到没有作不到。
防护XSS最佳的作法就是对数据进行严格的输出编码,使得攻击者提供的数据再也不被浏览器认为是脚本而被误执行。例如<script>在进行HTML编码后变成了<script>,而这段数据就会被浏览器认为只是一段普通的字符串,而不会被当作脚本执行了。
编码也不是件容易的事情,须要根据输出数据所在的上下文来进行相应的编码。例如刚才的例子,因为数据将被放置于HTML元素中,所以进行的是HTML编码,而若是数据将被放置于URL中,则须要进行URL编码,将其变为%3Cscript%3E。此外,还有JavaScript编码、CSS编码、HTML属性编码、JSON编码等等。好在现现在的前端开发框架基本上都默认提供了前端输出编码,这大大减轻了前端开发小伙伴们的工做负担。
其余的防护措施,例如设置CSP HTTP Header、输入验证、开启浏览器XSS防护等等都是可选项,缘由在于这些措施都存在被绕过的可能,并不能彻底保证能防护XSS攻击。不过它们和输出编码却能够共同协做实施纵深防护策略。
你能够查阅OWASP XSS Prevention Cheat Sheet,里面有关于XSS及其防护措施的详细说明。
有些时候咱们的前端页面须要用到第三方提供的页面组件,一般会以iframe的方式引入。典型的例子是使用iframe在页面上添加第三方提供的广告、天气预报、社交分享插件等等。
iframe在给咱们的页面带来更多丰富的内容和能力的同时,也带来了很多的安全隐患。由于iframe中的内容是由第三方来提供的,默认状况下他们不受咱们的控制,他们能够在iframe中运行JavaScirpt脚本、Flash插件、弹出对话框等等,这可能会破坏前端用户体验。
若是说iframe只是有可能会给用户体验带来影响,看似风险不大,那么若是iframe中的域名由于过时而被恶意攻击者抢注,或者第三方被黑客攻破,iframe中的内容被替换掉了,从而利用用户浏览器中的安全漏洞下载安装木马、恶意勒索软件等等,这问题可就大了。
还好在HTML5中,iframe有了一个叫作sandbox的安全属性,经过它能够对iframe的行为进行各类限制,充分实现“最小权限“原则。使用sandbox的最简单的方式就是只在iframe元素中添加上这个关键词就好,就像下面这样:
<iframe sandbox src="..."> ... </iframe>
sandbox还忠实的实现了“Secure By Default”原则,也就是说,若是你只是添加上这个属性而保持属性值为空,那么浏览器将会对iframe实施史上最严厉的调控限制,基本上来说就是除了容许显示静态资源之外,其余什么都作不了。好比不许提交表单、不许弹窗、不许执行脚本等等,连Origin都会被强制从新分配一个惟一的值,换句话讲就是iframe中的页面访问它本身的服务器都会被算做跨域请求。
另外,sandbox也提供了丰富的配置参数,咱们能够进行较为细粒度的控制。一些典型的参数以下:
allow-forms:容许iframe中提交form表单
allow-popups:容许iframe中弹出新的窗口或者标签页(例如,window.open(),showModalDialog(),target=”_blank”等等)
allow-scripts:容许iframe中执行JavaScript
allow-same-origin:容许iframe中的网页开启同源策略
更多详细的资料,能够参考iframe中关于sandbox的介绍。
有个词叫作防不胜防,咱们在经过iframe使用别人提供的内容时,咱们本身的页面也可能正在被不法分子放到他们精心构造的iframe或者frame当中,进行点击劫持攻击。
这是一种欺骗性比较强,同时也须要用户高度参与才能完成的一种攻击。一般的攻击步骤是这样的:
攻击者精心构造一个诱导用户点击的内容,好比Web页面小游戏;
将咱们的页面放入到iframe当中;
利用z-index等CSS样式将这个iframe叠加到小游戏的垂直方向的正上方;
把iframe设置为100%透明度;
受害者访问到这个页面后,肉眼看到的是一个小游戏,若是受到诱导进行了点击的话,实际上点击到的倒是iframe中的咱们的页面。
点击劫持的危害在于,攻击利用了受害者的用户身份,在其不知情的状况下进行一些操做。若是只是迫使用户关注某个微博帐号的话,看上去仿佛还能够承受,可是若是是删除某个重要文件记录,或者窃取敏感信息,那么形成的危害可就难以承受了。
有多种防护措施均可以防止页面遭到点击劫持攻击,例如Frame Breaking方案。一个推荐的防护方案是,使用X-Frame-Options:DENY这个HTTP Header来明确的告知浏览器,不要把当前HTTP响应中的内容在HTML Frame中显示出来。
关于点击劫持更多的细节,能够查阅OWASP Clickjacking Defense Cheat Sheet。
想象这样一个攻击场景:某网站容许用户在评论里上传图片,攻击者在上传图片的时候,看似提交的是个图片文件,实则是个含有JavaScript的脚本文件。该文件逃过了文件类型校验(这涉及到了恶意文件上传这个常见安全问题,可是因为和前端相关度不高所以暂不详细介绍),在服务器里存储了下来。接下来,受害者在访问这段评论的时候,浏览器会去请求这个假装成图片的JavaScript脚本,而此时若是浏览器错误的推断了这个响应的内容类型(MIME types),那么就会把这个图片文件当作JavaScript脚本执行,因而攻击也就成功了。
问题的关键就在于,后端服务器在返回的响应中设置的Content-Type Header仅仅只是给浏览器提供当前响应内容类型的建议,而浏览器有可能会自做主张的根据响应中的实际内容去推断内容的类型。
在上面的例子中,后端经过Content-Type Header建议浏览器按照图片来渲染此次的HTTP响应,可是浏览器发现响应中实际上是JavaScript,因而就擅自作主把这段响应当作JS脚原本解释执行,安全问题也就产生了。
浏览器根据响应内容来推断其类型,原本这是个很“智能”的功能,是浏览器强大的容错能力的体现,可是却会带来安全风险。要避免出现这样的安全问题,办法就是经过设置X-Content-Type-Options这个HTTP Header明确禁止浏览器去推断响应类型。
一样是上面的攻击场景,后端服务器返回的Content-Type建议浏览器按照图片进行内容渲染,浏览器发现有X-Content-Type-OptionsHTTP Header的存在,而且其参数值是nosniff,所以不会再去推断内容类型,而是强制按照图片进行渲染,那么由于实际上这是一段JS脚本而非真实的图片,所以这段脚本就会被浏览器看成是一个已经损坏或者格式不正确的图片来处理,而不是看成JS脚原本处理,从而最终防止了安全问题的发生。
更多关于X-Content-Type-Options的细节请参考这里。
本文对前端安全问题进行了一次梳理,介绍了其中4个典型的前端安全问题,包括它们发生的缘由以及防护办法。在下篇文章中,咱们将介绍其余的几个前端安全问题,敬请期待。