是个前端都应该了解的web安全知识(附一些较新的防范方法)
前言
对于很多刚开始工作的前端而言,web安全似乎是一个说不清道不明的东西。关于web安全,认真学习总结一下,其实就会发现它不难。本文通过面试提问的形式来一一进行总结,希望对于各位小伙伴理解web安全有所帮助。
1.前端有哪些攻击方式?
目前常见的web攻击方式主要分为:XSS攻击、CSRF攻击、点击劫持。
2.什么是XSS攻击?XSS攻击有哪几种类型?如何防范XSS攻击?
2.1 什么是XSS攻击?
XSS(Cross-Site Scripting,跨站脚本攻击)是一种代码注入攻击。攻击者在目标网站上注入恶意代码,当被攻击者登录网站时就会执行这些恶意代码。这些脚本可以读取cookie、session tokens或者其他敏感的网站信息,对用户进行钓鱼欺诈,甚至发起蠕虫攻击等。
XSS的本质是:恶意代码未经过滤,与网站正常的代码混在一起,而浏览器是无法辨别哪些脚本是恶意的,导致恶意脚本被执行。由于直接在用户的终端执行,恶意代码能够直接获取用户的信息,利用这些信息冒充用户向网站发起攻击者定义的请求。
举个简单的例子:
click mefunctiondoAttack(){while(true) { alert('u are under attack'); } }复制代码
这里在a标签里注入一个脚本,当用户点击后,浏览器会一直弹窗。在真实的网站攻击中,攻击者通过注入的这个脚本,它可以随意干坏事,这样是非常危险的。因为前端你用JavaScript进行的操作,它也一样能,想想是不是觉得很恐怖?
2.2 XSS攻击有哪几种类型?
根据攻击的来源,XSS可以分为存储型(持久型)、反射型(非持久型)、DOM型三种。
反射型XSS
当用户点击一个恶意链接,或者提交一个表单,或者进入一个恶意网站时,注入脚本进入被攻击者的网站。Web服务器将注入一个脚本,比如一个错误信息、搜索结果等,未进行过滤直接返回到用户的浏览器上。
反射型XSS的攻击步骤:
攻击者构造出特殊的url,其中包含恶意代码。
用户打开带有恶意代码的url时,网站服务端将恶意代码从url取出,拼接在HTML中返回给用户。
用户浏览器接收到响应后解析执行,混在其中的恶意代码也被执行。
恶意代码窃取用户数据并发送到攻击者的网站,或者冒充用户的行为,调用目标网站接口执行攻击者指定的操作。
反射型 XSS 漏洞常见于通过 URL 传递参数的功能,如网站搜索、跳转等。由于需要用户主动打开恶意的 URL 才能生效,攻击者往往会结合多种手段诱导用户点击。 注意Chrome 和 Safari 能够检测到 url 上的xss攻击,将网页拦截掉,但是其它浏览器不行,如Firefox。 如果不希望被前端拿到cookie,后端可以设置 httpOnly (不过这不是 XSS攻击 的解决方案,只能降低受损范围)。
DOM型XSS
DOM 型 XSS 攻击,实际上就是前端 JavaScript 代码不够严谨,把不可信的内容插入到了页面。在使用 .innerHTML、.outerHTML、.appendChild、document.write()等API时要特别小心,不要把不可信的数据作为 HTML 插到页面上,尽量使用 .innerText、.textContent、.setAttribute() 等。
DOM 型 XSS 的攻击步骤:
攻击者构造出特殊数据,其中包含恶意代码。
用户浏览器执行了恶意代码。
恶意代码窃取用户数据并发送到攻击者的网站,或者冒充用户的行为,调用目标网站接口执行攻击者指定的操作。
DOM 型 XSS 攻击中,取出和执行恶意代码由浏览器端完成,属于前端 JavaScript 自身的安全漏洞。
存储型XSS
恶意脚本永久存储在目标服务器上。当浏览器请求数据时,脚本从服务器传回并执行,影响范围比反射型和DOM型XSS更大。存储型XSS攻击的原因仍然是没有做好数据过滤:前端提交数据至服务端时,没有做好过滤;服务端在接受到数据时,在存储之前,没有做过滤;前端从服务端请求到数据,没有过滤输出。
存储型 XSS 的攻击步骤:
攻击者将恶意代码提交到目标网站的数据库中。
用户打开目标网站时,网站服务端将恶意代码从数据库取出,拼接在 HTML 中返回给浏览器。
用户浏览器接收到响应后解析执行,混在其中的恶意代码也被执行。
恶意代码窃取用户数据并发送到攻击者的网站,或者冒充用户的行为,调用目标网站接口执行攻击者指定的操作。
这种攻击常见于带有用户保存数据的网站功能,如论坛发帖、商品评论、用户私信等。
2.3 如何防范XSS攻击?
2.3.1 防范反射型XSS攻击
app.get('/welcome',function(req, res){//对查询参数进行编码,避免反射型 XSS攻击res.send(`${encodeURIComponent(req.query.type)}`); });复制代码
2.3.2 防范DOM型XSS攻击
防范 DOM 型 XSS 攻击的核心就是对输入内容进行转义(DOM 中的内联事件监听器和链接跳转都能把字符串作为代码运行,需要对其内容进行检查)。
对于url链接(例如图片的src属性),那么直接使用 encodeURIComponent 来转义。
非url,我们可以这样进行编码:
functionencodeHtml(str){if(!str)return'';returnstr.replace(/"/g,'"') .replace(/'/g,''') .replace(//g,'>') .replace(/&/g,'&');}复制代码
2.3.3 防范存储型XSS攻击
前端数据传递给服务器之前,先转义/过滤(防范不了抓包修改数据的情况)
服务器接收到数据,在存储到数据库之前,进行转义/过滤
前端接收到服务器传递过来的数据,在展示到页面前,先进行转义/过滤
2.3.4 CSP方式
CSP的全称是Content Security Policy,即内容安全策略。
CSP 的主要目标是减少和报告 XSS 攻击 ,XSS 攻击利用了浏览器对于从服务器所获取的内容的信任。恶意脚本在受害者的浏览器中得以运行,因为浏览器信任其内容来源,即使有的时候这些脚本并非来自于它本该来的地方。
CSP通过指定有效域——即浏览器认可的可执行脚本的有效来源——使服务器管理者有能力减少或消除XSS攻击所依赖的载体。一个CSP兼容的浏览器将会仅执行从白名单域获取到的脚本文件,忽略所有的其他脚本 (包括内联脚本和HTML的事件处理属性)。
作为一种终极防护形式,始终不允许执行脚本的站点可以选择全面禁止脚本执行。
如何使用CSP?
你可以使用 Content-Security-Policy HTTP头部 来指定你的策略,像这样:
Content-Security-Policy: policy
policy参数是一个包含了各种描述你的CSP策略指令的字符串。
比如一个网站管理者想要所有内容均来自站点的同一个源 (不包括其子域名):
Content-Security-Policy: default-src 'self'
详细的用法可以参考MDN,内容安全策略( CSP )
3. 什么是CSRF攻击?如何防范?
3.1 什么是CSRF攻击?
CSRF(Cross-site request forgery)跨站请求伪造:攻击者诱导受害者进入第三方网站,在第三方网站中,向被攻击网站发送跨站请求。利用受害者在被攻击网站已经获取的注册凭证,绕过后台的用户验证,达到冒充用户对被攻击的网站执行某项操作的目的。
典型的CSRF攻击流程:
受害者登录A站点,并保留了登录凭证(Cookie)。
攻击者诱导受害者访问了站点B。
站点B向站点A发送了一个请求,浏览器会默认携带站点A的Cookie信息。
站点A接收到请求后,对请求进行验证,并确认是受害者的凭证,误以为是无辜的受害者发送的请求。
站点A以受害者的名义执行了站点B的请求。
攻击完成,攻击者在受害者不知情的情况下,冒充受害者完成了攻击。
3.2 如何防范CSRF攻击?
3.2.1 主流方式
添加验证码(体验不好)
判断请求的来源:检测Referer(并不安全,Referer可以被更改)
使用Token(主流)
CSRF攻击之所以能够成功,是因为服务器误把攻击者发送的请求当成了用户自己的请求。那么我们可以要求所有的用户请求都携带一个CSRF攻击者无法获取到的Token。服务器通过校验请求是否携带正确的Token,来把正常的请求和攻击的请求区分开。跟验证码类似,只是用户无感知。
服务端给用户生成一个token,加密后传递给用户
用户在提交请求时,需要携带这个token
服务端验证token是否正确
3.2.2 启用cookies的SameSite属性
SameSite的属性值有3个:
strict: Cookie只会在第一方上下文中发送,不会与第三方网站发起的请求一起发送。
lex: Cookies允许与顶级一起发送,并将与第三方网站发起的GET请求一起发送。这是浏览器中的默认值。
none: Cookie将在所有上下文中发送,即允许跨域发送。
注意:以前None是默认值,但最近的浏览器版本将Lax作为默认值,以便对某些类型的跨站点请求伪造(csrf)攻击具有相当强的防御能力。
4. 什么是点击劫持攻击?如何防范?
4.1 什么是点击劫持攻击?
点击劫持是指在一个Web页面中隐藏了一个透明的iframe,用外层假页面诱导用户点击,实际上是在隐藏的frame上触发了点击事件进行一些用户不知情的操作。
典型的点击劫持攻击流程:
攻击者构建了一个非常有吸引力的网页
将被攻击的页面放置在当前页面的 iframe 中
使用样式将 iframe 叠加到非常有吸引力内容的上方
将iframe设置为100%透明
你被诱导点击了网页内容,你以为你点击的是***,而实际上,你成功被攻击了。
4.2 如何防范点击劫持?
4.2.1 frame busting
if(top.location !==window.location) { top.location =window.location;}复制代码
需要注意的是: HTML5中iframe的 sandbox 属性、IE中iframe的security 属性等,都可以限制iframe页面中的JavaScript脚本执行,从而可以使得 frame busting 失效。
4.2.2 X-FRAME-OPTIONS
X-FRAME-OPTIONS是微软提出的一个http头,专门用来防御利用iframe嵌套的点击劫持攻击。并且在IE8、Firefox3.6、Chrome4以上的版本均能很好的支持。可以设置为以下值:
DENY: 拒绝任何域加载
SAMEORIGIN: 允许同源域下加载
ALLOW-FROM: 可以定义允许frame加载的页面地址
5. 总结
以上谈到了3种web攻击方式,分别是XSS攻击、CSRF攻击、点击劫持,并给出了具体的防范方式。当然,只有在实践中不断地使用这些技术,才能对web安全有更深刻的认知。