前端安全(一)XSS攻击原理及防范

 

前端是直面用户的窗口,其安全性却是最容易被忽略的一环。本文将介绍:

一、什么是XSS攻击

1.1 定义

1.2 XSS攻击的危害

二、 XSS攻击类型

2.1 反射型攻击

2.2 存储型攻击

2.3 DOM型攻击

2.4 三种攻击类型的区别

三、 如何防范XSS攻击

3.1 设置Cookie HttpOnly 为 true

3.2 纯前端渲染

3.3 使用合适的转义库

3.4  预防DOM型XSS攻击

四、 线上XSS检测

4.1 特殊恶意字符串

4.2 扫描工具

五、总结


一、什么是XSS攻击

1.1 定义

XSS攻击的本质是,在url参数中加入恶意的javascript代码,通过浏览器解析和运行恶意代码,达到恶意攻击用户的目的。

官方解释:

XSS是跨站脚本攻击(Cross Site Scripting),为不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS。恶意攻击者往Web页面里插入恶意Script代码,当用户浏览该页之时,嵌入其中Web里面的Script代码会被执行,从而恶意攻击用户的目的。

 

1.2 XSS攻击的危害

攻击者可获取用户的敏感信息如 Cookie、SessionID 等,进而危害数据安全。或是通过前端请求操作数据库,获取数据库内容或修改数据库内容。

 

二、 XSS攻击类型

XSS攻击分为反射型攻击和存储型攻击。

2.1 反射型攻击

反射型攻击也叫非持久型XSS攻击,即在请求时将恶意代码插入URL中,作为参数提交到服务器。服务器解析数据并将响应数据返回到浏览器中,最终由浏览器执行。

2.1.1 攻击步骤

  1. 攻击者创造出带有恶意代码的特殊url,并发送到服务器
  2. 用户打开这个特殊的url,服务器网站将参数从url中解出,拼接在响应中返回给浏览器
  3. 浏览器解析响应时,这段恶意代码也被浏览器执行
  4. 这段恶意代码可以窃取用户信息并发送到攻击者网站,或冒充用户进行指定操作。

 

2.1.2 例子

如:

http://localhost:8080/helloController/search?name=<script>alert("hey!")</script>

http://localhost:8080/helloController/search?name=<img src='w.123' onerror='alert("hey!")'>

http://localhost:8080/helloController/search?name=<a onclick='alert("hey!")'>点我</a>

 

 

2.2 存储型攻击

存储型攻击也叫持久型攻击,即一次攻击成功后,下一次请求时就不用再带上恶意XSS代码了。第一次注入的XSS代码会被服务器存储(缓存或数据库),且在下一次被前端从服务器获取,返回到浏览器时被浏览器执行。常见于带有用户保存数据的网站功能,如论坛发帖、商品评论、用户私信等。

2.2.1 攻击步骤

存储型 XSS 的攻击步骤:

  1. 攻击者将恶意代码提交到目标网站的数据库中。
  2. 用户打开目标网站时,网站服务端将恶意代码从数据库取出,拼接在 HTML 中返回给浏览器。
  3. 用户浏览器接收到响应后解析执行,混在其中的恶意代码也被执行。
  4. 恶意代码窃取用户数据并发送到攻击者的网站,或者冒充用户的行为,调用目标网站接口执行攻击者指定的操作。

 

2.2.2 恶意盗取用户信息

常见在留言板,IM聊天软件中出现。如某web聊天软件中,小王给小明发了一条XSS攻击消息

<script>alert('你被XSS攻击啦')</script>

当小明接收到这条消息时,就会出现一个内容为 “你被XSS攻击啦” 的弹窗。若这条消息没有被删掉,则小明每次打开这个消息的窗口,弹窗都会弹出来,因为这段XSS恶意代码已经被执行了。

他可以被包装得更具有隐蔽性

hello,你好<script>xxxxxxxxxx</script>

这种攻击常用于窃取用户信息,如cookie,token,账号密码等

 

2.2.3 插入图片

依旧是留言板,当留言板浏览器执行到这段代码时,会出现一张图片,点击图片,则会被重定向到另一个网站

< img onclick="window.location.href='http://www.baidu.com'" width='300' src='img/webwxgetmsgimg.jpg'/>

 

2.2.4 流量劫持、恶意跳转

当用户打开网址时,会被恶意重定向到指定的网址

<script>window.location.href="http://www.baidu.com";</script>

2.3 DOM型攻击

2.3.1 攻击步骤

  1. 攻击者构造出特殊的 URL,其中包含恶意代码。
  2. 用户打开带有恶意代码的 URL。
  3. 用户浏览器接收到响应后解析执行,前端 JavaScript 取出 URL 中的恶意代码并执行。
  4. 恶意代码窃取用户数据并发送到攻击者的网站,或者冒充用户的行为,调用目标网站接口执行攻击者指定的操作。

 

2.4 三种攻击类型的区别

攻击类型恶意代码存储位置插入点解决端
反射型XSSURLHTML服务端
存储型XSS后端数据库或缓存中HTML服务端
DOM型XSS后端数据库/前端存储/URL前端JAVASCRIPT前端

 

三、 如何防范XSS攻击

3.1 设置Cookie HttpOnly 为 true

服务端可以通过设置 HttpOnly 来防止XSS代码获取到用户的cookie。

@RequestMapping("/login")
    @ResponseBody
    public void login(HttpServletRequest request, HttpServletResponse response) throws IOException {
        ......
        Cookie cookie = new Cookie("access_token", UUID.randomUUID().toString());
        cookie.setHttpOnly(true); // 此处设置HttpOnly为true
        cookie.setPath("/");
        cookie.setDomain("localhost");
        response.addCookie(cookie);
        response.sendRedirect("http://localhost:8088/index.html");
    }

 

3.2 纯前端渲染

纯前端渲染即避免在前端代码中出现html拼接的情况。一个合理干净的前端代码应该是:

  1. 前端页面只负责加载一个静态dom
  2. 通过执行写好的JavaScript,通过网络请求的方式获取数据
  3. 调用DOM Api将数据更新到页面上

在很多内部、管理系统中,采用纯前端渲染是非常合适的,但纯前端渲染,会带来以下问题:

  •  无法防止DOM 型 XSS 漏洞(例如 onload 事件和 href 中的 javascript:xxx
  • 对于性能要求高,或有 SEO 需求的页面,我们仍然要面对拼接 HTML 的问题

 

3.3 使用合适的转义库

3.3.1  前端转义函数

/** 
 * @function escapeHTML 转义html脚本 < > & " ' 
 * @param a - 
 *            字符串 
 */  
escapeHTML: function(a){  
    a = "" + a;  
    return a.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");;  
},  
/** 
 * @function unescapeHTML 还原html脚本 < > & " ' 
 * @param a - 
 *            字符串 
 */  
unescapeHTML: function(a){  
    a = "" + a;  
    return a.replace(/</g, "<").replace(/>/g, ">").replace(/&/g, "&").replace(/"/g, '"').replace(/'/g, "'");  
},

3.3.2 后端转义库

Java 工程里,常用的转义库为 org.owasp.encode

 

3.4  预防DOM型XSS攻击

DOM型XSS攻击,实际是前端JavaScript将不可信的数据当作代码执行力。

应尽量使用 .textContent.setAttribute() 代替.innerHTML.outerHTMLdocument.write() ,若必须使用时要特别小心,不要把不可信的数据作为 HTML 插到页面上

如果用 Vue/React 技术栈,并且不使用 v-html/dangerouslySetInnerHTML 功能,就在前端 render 阶段避免 innerHTMLouterHTML 的 XSS 隐患。

DOM 中的内联事件监听器,如 locationonclickonerroronloadonmouseover 等,<a> 标签的 href 属性,JavaScript 的 eval()setTimeout()setInterval() 等,都能把字符串作为代码运行。如果不可信的数据拼接到字符串中传递给这些 API,很容易产生安全隐患,请务必避免。

 

四、 线上XSS检测

4.1 特殊恶意字符串

将这段字符串输入到输入框中提交这个字符串,或者把它拼接到 URL 参数上,就可以进行检测了

http://xxx/search?keyword=jaVasCript%3A%2F*-%2F*%60%2F*%60%2F*%27%2F*%22%2F**%2F(%2F*%20*%2FoNcliCk%3Dalert()%20)%2F%2F%250D%250A%250d%250a%2F%2F%3C%2FstYle%2F%3C%2FtitLe%2F%3C%2FteXtarEa%2F%3C%2FscRipt%2F--!%3E%3CsVg%2F%3CsVg%2FoNloAd%3Dalert()%2F%2F%3E%3E

 

4.2 扫描工具

除了手动检测之外,还可以使用自动扫描工具寻找 XSS 漏洞,例如 ArachniMozilla HTTP Observatoryw3af 等

 

五、总结

充分遵循以下原则,能够降低XSS攻击得手的概率

  • 利用模板引擎
    开启模板引擎自带的 HTML 转义功能。例如:
    在 ejs 中,尽量使用 <%= data %> 而不是 <%- data %>
    在 doT.js 中,尽量使用 {{! data } 而不是 {{= data }
    在 FreeMarker 中,确保引擎版本高于 2.3.24,并且选择正确的 freemarker.core.OutputFormat
  • 避免内联事件
    尽量不要使用 onLoad="onload('{{data}}')"onClick="go('{{action}}')" 这种拼接内联事件的写法。在 JavaScript 中通过 .addEventlistener() 事件绑定会更安全。
  • 避免拼接 HTML
    前端采用拼接 HTML 的方法比较危险,如果框架允许,使用 createElementsetAttribute 之类的方法实现。或者采用比较成熟的渲染框架,如 Vue/React 等。
  • 时刻保持警惕
    在插入位置为 DOM 属性、链接等位置时,要打起精神,严加防范。
  • 增加攻击难度,降低攻击后果
    通过 CSP、输入长度配置、接口安全措施等方法,增加攻击的难度,降低攻击的后果。
  • 主动检测和发现
    可使用 XSS 攻击字符串和自动扫描工具寻找潜在的 XSS 漏洞。

 

参考网站:

感觉大佬的无私分享

Java防止XSS攻击获取Cookie:  https://www.cnblogs.com/mao2080/p/9520185.html

网络攻击-XSS攻击详解:https://www.cnblogs.com/mao2080/p/9460397.html

美团前端安全系列(一):https://www.cnblogs.com/meituantech/p/9718677.html

 

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值