前端安全系列

前端安全系列(一):如何防止XSS攻击?

参考链接:https://www.cnblogs.com/unclekeith/p/7750681.htmlhttps://www.freebuf.com/articles/web/185654.html

XSS定义

前端安全系列
XSS, 即为(Cross Site Scripting), 中文名为跨站脚本, 是发生在目标用户的浏览器层面上的,当渲染DOM树的过程成发生了不在预期内执行的JS代码时,就发生了XSS攻击。


跨站脚本的重点不在‘跨站’上,而在于‘脚本’上。大多数XSS攻击的主要方式是嵌入一段远程或者第三方域上的JS代码。实际上是在目标网站的作用域下执行了这段js代码。

XSS 的本质是:

  • 恶意代码未经过滤,与网站正常的代码混在一起;浏览器无法分辨哪些脚本是可信的,导致恶意脚本被执行。而由于直接在用户的终端执行,恶意代码能够直接获取用户的信息,或者利用这些信息冒充用户向网站发起攻击者定义的请求。在部分情况下,由于输入的限制,注入的恶意脚本比较短。但可以通过引入外部的脚本,并由浏览器执行,来完成比较复杂的攻击策略。

XSS危害

  • 通过document.cookie盗取cookie
  • 使用js或css破坏页面正常的结构与样式
  • 流量劫持(通过访问某段具有window.location.href定位到其他页面
  • Dos攻击:利用合理的客户端请求来占用过多的服务器资源,从而使合法用户无法得到服务器响应。
  • 利用iframe、frame、XMLHttpRequest或上述Flash等方式,以(被攻击)用户的身份执行一些管理动作,或执行一些一般的如发微博、加好友、发私信等操作。
  • 利用可被攻击的域受到其他域信任的特点,以受信任来源的身份请求一些平时不允许的操作,如进行不当的投票活动。

对cookie的保护

  • 对重要的cookie设置httpOnly, 防止客户端通过document.cookie读取cookie。服务端可以设置此字段。

防御总结

  • XSS 一般利用js脚步读取用户浏览器中的Cookie,而如果在服务器端对 Cookie 设置了HttpOnly 属性,那么js脚本就不能读取到cookie,但是浏览器还是能够正常使用cookie。一般的Cookie都是从document对象中获得的,现在浏览器在设置 Cookie的时候一般都接受一个叫做HttpOnly的参数,跟domain等其他参数一样,一旦这个HttpOnly被设置,你在浏览器的 document对象中就看不到Cookie了,而浏览器在浏览的时候不受任何影响,因为Cookie会被放在浏览器头中发送出去(包括ajax的时 候),应用程序也一般不会在js里操作这些敏感Cookie的,对于一些敏感的Cookie我们采用HttpOnly,对于一些需要在应用程序中用js操作的cookie我们就不予设置,这样就保障了Cookie信息的安全也保证了应用。
  • 对输入和URL参数进行过滤:如将容易引起xss漏洞的半角字符直接替换成全角字符
    前端安全系列
  • 对输出进行编码:在输出数据之前对潜在的威胁的字符进行编码、转义是防御XSS攻击十分有效的措施。

一个案例

某天,公司需要一个搜索页面,根据 URL 参数决定关键词的内容。小明很快把页面写好并且上线。代码如下:

 < input  type = "text"  value = "<%= getParameter(" keyword ") %> ">
 < button > 搜索 </ button > 
 < div > 
 您搜索的关键词是: < %=  getParameter (" keyword ") %> 
 </ div > 

然而,在上线后不久,小明就接到了安全组发来的一个神秘链接:

http://xxx/search?keyword=">

小明带着一种不祥的预感点开了这个链接 [请勿模仿,确认安全的链接才能点开] 。果然,页面中弹出了写着”XSS”的对话框。

可恶,中招了!小明眉头一皱,发现了其中的奥秘:

当浏览器请求 http://xxx/search?keyword=">,拼接到 HTML 中返回给浏览器。形成了如下的 HTML:

 < input  type = "text"  value = "" > < script > alert( 'XSS' ); </ script > ">
 < button > 搜索 </ button > 
 < div > 
 您搜索的关键词是:"> < script > alert( 'XSS' ); </ script > 
 </ div > 

浏览器无法分辨出 是恶意代码,因而将其执行。

这里不仅仅 div 的内容被注入了,而且 input 的 value 属性也被注入, alert 会弹出两次。

面对这种情况,我们应该如何进行防范呢?

其实,这只是浏览器把用户的输入当成了脚本进行了执行。那么只要告诉浏览器这段内容是文本就可以了。

聪明的小明很快找到解决方法,把这个漏洞修复:

 < input  type = "text"  value = "<%= escapeHTML(getParameter(" keyword ")) %> ">
 < button > 搜索 </ button > 
 < div > 
 您搜索的关键词是: < %=  escapeHTML ( getParameter (" keyword ")) %> 
 </ div > 

escapeHTML() 按照如下规则进行转义:

字符 转义后的字符
& &amp;
< &lt;
> &gt;
" &quot;
&#x27;
/ &#x2F;

经过了转义函数的处理后,最终浏览器接收到的响应为:

 < input  type = "text"  value = "&quot;&gt;&lt;script&gt;alert(&#x27;XSS&#x27;);&lt;&#x2F;script&gt;" > 
 < button > 搜索 </ button > 
 < div > 
 您搜索的关键词是:&quot;&gt;&lt;script&gt;alert(&#x27;XSS&#x27;);&lt;&#x2F;script&gt;
 </ div > 

恶意代码都被转义,不再被浏览器执行,而且搜索词能够完美的在页面显示出来。

通过这个事件,小明学习到了如下知识:

通常页面中包含的用户输入内容都在固定的容器或者属性内,以文本的形式展示。

攻击者利用这些页面的用户输入片段,拼接特殊格式的字符串,突破原有位置的限制,形成了代码片段。

攻击者通过在目标网站上注入脚本,使之在用户的浏览器上运行,从而引发潜在风险。

通过 HTML 转义,可以防止 XSS 攻击。 [事情当然没有这么简单啦!请继续往下看] 。

自从上次事件之后,小明会小心的把插入到页面中的数据进行转义。而且他还发现了大部分模板都带有的转义配置,让所有插入到页面中的数据都默认进行转义。这样就不怕不小心漏掉未转义的变量啦,于是小明的工作又渐渐变得轻松起来。
还有其他几种攻击,参考:https://www.freebuf.com/articles/web/185654.html

小明的例子讲完了,下面我们来系统的看下 XSS 有哪些注入的方法:

在 HTML 中内嵌的文本中,恶意内容以 script 标签形成注入。
在内联的 JavaScript 中,拼接的数据突破了原本的限制(字符串,变量,方法名等)。
在标签属性中,恶意内容包含引号,从而突破属性值的限制,注入其他属性或者标签。
在标签的 href、src 等属性中,包含 javascript: 等可执行代码。
在 onload、onerror、onclick 等事件中,注入不受控制代码。
在 style 属性和标签中,包含类似 background-image:url(“javascript:…”);的代码(新版本浏览器已经可以防范)。

在 style 属性和标签中,包含类似 expression(…) 的 CSS 表达式代码(新版本浏览器已经可以防范)。

总之,==如果开发者没有将用户输入的文本进行合适的过滤,就贸然插入到 HTML 中,这很容易造成注入漏洞。==攻击者可以利用漏洞,构造出恶意的代码指令,进而利用恶意代码危害数据安全。

前端安全系列(二):CSRF

定义

  • CSRF(Cross-site request forgery),中文名称:跨站请求伪造,也被称为:one click attack/session riding,缩写为:CSRF/XSRF。
  • hack利用用户登录状态操作隐私或者敏感功能。
    你这可以这么理解CSRF攻击:攻击者盗用了你的身份,以你的名义发送恶意请求。CSRF能够做的事情包括:以你名义发送邮件,发消息,盗取你的账号,甚至于购买商品,虚拟货币转账…造成的问题包括:个人隐私泄露以及财产安全。
    前端安全系列
    hack主要是利用cookie的信息
    1.get请求尽量不要用
    2.加入智能复杂的验证码
    3.http 头header里面有referer,可以记录当前请求的来源地址,若不是该网站,则直接拒绝。【在特定的,例如转账借口上加拦截器,检查referer,但并不是完全完全的】
    4.【常用,关键在token的保密性和随机性?①服务端产生token,随机产生的、②服务端把token放在放到session里面或MySQL的缓存中?,
    ③客户端可把token放在区域或者表单中,可用js提取,在post请求时把token带给服务端
    ④每次请求过来,服务端就要验证,且验证通过后要销毁,否咋被hack拿走

    前端安全系列
    5.自定义header