前端安全系列
前端安全系列(一):如何防止XSS攻击?
参考链接:https://www.cnblogs.com/unclekeith/p/7750681.html 、https://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 >
然而,在上线后不久,小明就接到了安全组发来的一个神秘链接:
小明带着一种不祥的预感点开了这个链接 [请勿模仿,确认安全的链接才能点开] 。果然,页面中弹出了写着”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() 按照如下规则进行转义:
字符 | 转义后的字符 |
---|---|
& | & |
< | < |
> | > |
" | " |
’ | ' |
/ | / |
经过了转义函数的处理后,最终浏览器接收到的响应为:
< input type = "text" value = ""><script>alert('XSS');</script>" >
< button > 搜索 </ button >
< div >
您搜索的关键词是:"><script>alert('XSS');</script>
</ 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