XSS¶
0x01 漏洞描述¶
XSS全称为Cross Site Scripting,为了和CSS分开简写为XSS,中文名为跨站脚本。该漏洞发生在用户端,是指恶意攻击者往Web站点里插入恶意脚本代码,当用户浏览该网站时,嵌入其里面的脚本代码会被执行,从而达到恶意用户的特殊目的。
根据是否写入数据看来分类主要有反射性和存储型两大类。
- 反射型跨站脚本(Reflected XSS)
- 储存型跨站脚本(Persistent XSS)
区别:存储型XSS的恶意代码存在数据库里,反射型XSS的恶意代码存在URL里。
0x02 常见应用场景¶
2.1 反射型XSS¶
反射性XSS通常需要被攻击者点击对应的链接才能触发,且受到XSS Auditor、NoScript等防御手段的影响较大。
反射型xss应用场景:比如搜索、查询,接口调用,跳转,http头获取参数地理位置,cookie,id,referer等一切输入、输出的地方
2.2 存储型XSS¶
存储型XSS由于存储在数据库或其他持久性中间件中,所以用户只需浏览了包含恶意代码的页面即可在用户无感知的情况下触发。
反射型xss应用场景:比如注册处、用户名、地址、头像等信息,用户反馈、留言、修改个人信息、发表文章、评论、转发、私信等一切输入输出的地方。
0x03 漏洞危害¶
- 钓鱼欺骗:最典型的就是利用目标网站的反射型跨站脚本漏洞将目标网站重定向到钓鱼网站,或者注入钓鱼JavaScript以监控目标网站的表单输入,甚至发起基于DHTML更高级的钓鱼攻击方式。
- 网站挂马:跨站后利用IFrame嵌入隐藏的恶意网站或者将被攻击者定向到恶意网站上,或者弹出恶意网站窗口等方式都可以进行挂马攻击。
- 身份盗用:Cookie是用户对于特定网站的身份验证标志,XSS可以盗取用户的Cookie,就可以获取到用户对网站的操作权限,从而查看用户隐私信息。
- 用户劫持:一些高级的XSS,比如xss蠕虫等。
- 控制受害者机器向其他系统发起攻击。
0x04 修复建议¶
4.1 代码层面¶
4.1.1 在服务端进行输入验证(输入验证)¶
服务器后端进行输入验证,包括输入的数据类型、数据长度、数据格式、特殊字符等进行验证。
4.1.2 数据输出实体编码(输出编码)¶
输出编码手段主要有3种编码:URL编码、HTML编码和JavaScript编码。
JAVA:开源的ESAPI library
;框架(Spring:HtmlUtils.htmlEscape
) PHP:使用htmlspecialchars
等函数进行过滤输出
4.2 其他层面¶
4.2.1 使用模版引擎¶
开启模板引擎自带的 HTML 转义功能。例如: 在 ejs 中,尽量使用 <%= data %>
而不是 <%- data %>
; 在 doT.js 中,尽量使用{{! data }
而不是 {{= data }
; 在 FreeMarker 中,确保引擎版本高于 2.3.24,并且选择正确的 freemarker.core.OutputFormat
。
4.2.2 避免内敛事件¶
尽量不要使用 onLoad="onload('{{data}}')"
、onClick="go('{{action}}')"
这种拼接内联事件的写法。在 JavaScript 中通过 .addEventlistener()
事件绑定会更安全。
4.2.3 避免拼接 HTML¶
前端采用拼接 HTML 的方法比较危险,如果框架允许,使用 createElement、setAttribute 之类的方法实现。或者采用比较成熟的渲染框架,如 Vue/React 等。
4.2.4 使用CSP¶
Content Security Policy:禁止加载外域代码,防止复杂的攻击逻辑;禁止外域提交,网站被攻击后,用户的数据不会泄露到外域;禁止内联脚本执行;禁止未授权的脚本执行。
4.2.5 使用httponly¶
HTTP-only Cookie: 禁止 JavaScript 读取某些敏感 Cookie,攻击者完成 XSS 注入后也无法窃取此 Cookie。httponly无法完全的防御xss漏洞,它只是规定了不能使用js去获取cookie的内容,因此它只能防御利用xss进行cookie劫持的问题。Httponly是在set-cookie时标记的,可对单独某个参数标记也可对全部参数标记。由于设置httponly的方法比较简单,使用也很灵活,并且对防御cookie劫持非常有用,因此已经渐渐成为一种默认的标准。