1、概述php
“安全”是个很大的话题,各类安全问题的类型也是种类繁多。若是咱们把安全问题按照所发生的区域来进行分类的话,那么全部发生在后端服务器、应用、服务当中的安全问题就是“后端安全问题”,全部发生在浏览器、单页面应用、Web页面当中的安全问题则算是“前端安全问题”。好比说,SQL注入漏洞发生在后端应用中,是后端安全问题,跨站脚本攻击(XSS)则是前端安全问题,由于它发生在用户的浏览器里。前端
2、常见前端安全问题及防御算法
一、跨站脚本攻击(Cross-Site Scripting)后端
XSS是跨站脚本攻击(Cross-Site Scripting)的简称。XSS这类安全问题发生的本质缘由在于:浏览器错误的将攻击者提供的用户输入数据当作JavaScript脚本给执行了。
XSS有几种不一样的分类办法,例如按照恶意输入的脚本是否在应用中存储,XSS被划分为“存储型XSS”和“反射型XSS”,若是按照是否和服务器有交互,又能够划分为“Server Side XSS”和“DOM based XSS”。
不管怎么分类,XSS漏洞始终是威胁用户的一个安全隐患。攻击者能够利用XSS漏洞来窃取包括用户身份信息在内的各类敏感信息、修改Web页面以欺骗用户,甚至控制受害者浏览器,或者和其余漏洞结合起来造成蠕虫攻击,等等。总之,关于XSS漏洞的利用,只有想不到没有作不到。浏览器
如何防护?安全
对数据进行严格的输出编码,使得攻击者提供的数据再也不被浏览器认为是脚本而被误执行。例如<script>在进行HTML编码后变成了<script>,这段数据就不会被当作脚本执行了。
须要根据输出数据所在的上下文来进行相应的编码。数据放置于HTML元素中,需进行HTML编码,放置于URL中,须要进行URL编码。此外,还有JavaScript编码、CSS编码、HTML属性编码、JSON编码等等。(一些主流前端开发框架基本上都默认提供了前端输出编码,这大大减轻了前端开发小伙伴们的工做负担)
其余的防护措施,例如设置CSP HTTP Header、输入验证、开启浏览器XSS防护等等都是可选项,缘由在于这些措施都存在被绕过的可能,并不能彻底保证能防护XSS攻击。不过它们和输出编码却能够共同协做实施纵深防护策略。服务器
二、使用iframe的风险架构
有时前端页面须要用到第三方提供的页面组件,一般会以iframe的方式引入。典型的例子是使用iframe在页面上添加第三方提供的广告、天气预报、社交分享插件等等。
iframe在给咱们的页面带来更多丰富的内容和能力的同时,也带来了很多的安全隐患。由于iframe中的内容是由第三方来提供的,默认状况下他们不受咱们的控制,他们能够在iframe中运行JavaScirpt脚本、Flash插件、弹出对话框等等,这可能会破坏前端用户体验。
若是说iframe只是有可能会给用户体验带来影响,看似风险不大,那么若是iframe中的域名由于过时而被恶意攻击者抢注,或者第三方被黑客攻破,iframe中的内容被替换掉了,从而利用用户浏览器中的安全漏洞下载安装木马、恶意勒索软件等等,这问题可就大了。框架
如何防护?前后端分离
在HTML5中,iframe有个sandbox安全属性,经过它能够对iframe的行为进行各类限制,充分实现“最小权限“原则。例如: <iframe sandbox src="..."> ... </iframe>
sandbox提供了丰富的配置参数,能够进行较为细粒度的控制。
allow-forms:容许iframe中提交form表单
allow-popups:容许iframe中弹出新的窗口或者标签页(例如,window.open(),showModalDialog(),target=”_blank”等等)
allow-scripts:容许iframe中执行JavaScript
allow-same-origin:容许iframe中的网页开启同源策略
更多详细的资料,能够参考iframe中关于sandbox的介绍。
三、点击劫持
这是一种欺骗性比较强,同时也须要用户高度参与才能完成的一种攻击。一般的攻击步骤是这样的:
一、攻击者构造一个诱导用户点击的内容,如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。连接地址:https://www.owasp.org/index.php/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-Options HTTP Header的存在,而且其参数值是nosniff,所以不会再去推断内容类型,而是强制按照图片进行渲染,从而最终防止了安全问题的发生。
更多关于X-Content-Type-Options的细节请参考:https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options
五、不安全的第三方依赖包
现现在进行应用开发,不管是后端服务器应用仍是前端应用开发,绝大多数时候咱们都是在借助开发框架和各类类库进行快速开发。
这样作的好处显而易见,可是与此同时安全风险也在不断累积——应用使用了如此多的第三方代码,不论应用本身的代码的安全性有多高,一旦这些来自第三方的代码有安全漏洞,那么对应用总体的安全性依然会形成严峻的挑战。
如何防护?
尽可能减小第三方依赖,选用相对成熟的依赖包。
使用自动化工具检查这些第三方代码有没有安全问题,好比NSP(Node Security Platform),Snyk等等。
六、HTTPS中间人攻击
即便是服务器端开启了HTTPS,也仍是存在安全隐患,黑客能够利用SSL Stripping这种攻击手段,强制让HTTPS降级回HTTP,从而继续进行中间人攻击。
问题的本质在于浏览器发出去第一次请求就被攻击者拦截了下来并作了修改,根本不给浏览器和服务器进行HTTPS通讯的机会。大体过程以下,用户在浏览器里输入URL的时候每每不是从https://开始的,而是直接从域名开始输入,随后浏览器向服务器发起HTTP通讯,然而因为攻击者的存在,它把服务器端返回的跳转到HTTPS页面的响应拦截了,而且代替客户端和服务器端进行后续的通讯。因为这一切都是暗中进行的,因此使用前端应用的用户对此毫无察觉。
如何防护?
解决这个安全问题的办法是使用HSTS(HTTP Strict Transport Security),它经过下面这个HTTP Header以及一个预加载的清单,来告知浏览器在和网站进行通讯的时候强制性的使用HTTPS,而不是经过明文的HTTP进行通讯:
Strict-Transport-Security: max-age=; includeSubDomains; preload
这里的“强制性”表现为浏览器不管在何种状况下都直接向服务器端发起HTTPS请求,而再也不像以往那样从HTTP跳转到HTTPS。另外,当遇到证书或者连接不安全的时候,则首先警告用户,而且再也不让用户选择是否继续进行不安全的通讯。
7 、本地存储数据泄露
随着先后端分离,尤为是后端服务无状态化架构风格的兴起,随着SPA应用大量出现,存储在前端数据量也在逐渐增多。
前端应用是彻底暴露在用户以及攻击者面前的,在前端存储任何敏感、机密的数据,都会面临泄露的风险,就算是在前端经过JS脚本对数据进行加密基本也无济于事。
尽管有浏览器的同源策略限制,可是若是前端应用有XSS漏洞,那么本地存储的全部数据就均可能被攻击者的JS脚本读取到。若是用户在公用电脑上使用了这个前端应用,那么当用户离开后,这些数据是否也被完全清除了呢?前端对数据加密后再存储看上去是个防护办法,但其实仅仅提升了一点攻击门槛而已,由于加密所用到的密钥一样存储在前端,有耐心的攻击者依然能够攻破加密这道关卡。
因此,在前端存储敏感、机密信息始终都是一件危险的事情,推荐的作法是尽量不在前端存这些数据。
如何防护?
8 、CDN劫持/污染
以出于性能考虑,前端应用一般会把一些静态资源存放到CDN上,再提升前端应用的访问速度的同时也隐含了一个新的安全风险。
若是攻击者劫持了CDN,或者对CDN中的资源进行了污染,那么咱们的前端应用拿到的就是有问题的JS脚本或者Stylesheet文件。这种攻击方式形成的效果和XSS跨站脚本攻击类似。
如何防护?
防护这种攻击的办法是使用浏览器提供的SRI(Subresource Integrity)功能。
每一个资源文件都有一个SRI值。由两部分组成,减号(-)左侧是生成SRI值用到的哈希算法名,右侧是通过Base64编码后的该资源文件的Hash值。<script src="“https://example.js”" integrity="“sha384-eivAQsRgJIi2KsTdSnfoEGIRTo25NCAqjNJNZalV63WKX3Y51adIzLT4So1pk5tX”"/>
浏览器在处理这个script元素的时候,就会检查对应的JS脚本文件的完整性,看其是否和script元素中integrity属性指定的SRI值一致,若是不匹配,浏览器则会停止对这个JS脚本的处理。