前端安全(一)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代码会被执行,从而恶意攻击用户的目的。

前端安全(一)XSS攻击原理及防范_第1张图片

 

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=

http://localhost:8080/helloController/search?name=

http://localhost:8080/helloController/search?name=点我

 

前端安全(一)XSS攻击原理及防范_第2张图片

前端安全(一)XSS攻击原理及防范_第3张图片

 

2.2 存储型攻击

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

2.2.1 攻击步骤

存储型 XSS 的攻击步骤:

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

 

2.2.2 恶意盗取用户信息

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

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

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

hello,你好

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

 

2.2.3 插入图片

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

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

 

2.2.4 流量劫持、恶意跳转

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

2.3 DOM型攻击

2.3.1 攻击步骤

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

 

2.4 三种攻击类型的区别

攻击类型 恶意代码存储位置 插入点 解决端
反射型XSS URL HTML 服务端
存储型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, "'");;  
},  
/** 
 * @function unescapeHTML 还原html脚本 < > & " ' 
 * @param a - 
 *            字符串 
 */  
unescapeHTML: function(a){  
    a = "" + a;  
    return a.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 等, 标签的 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 漏洞,例如 Arachni、Mozilla HTTP Observatory、w3af 等

 

五、总结

充分遵循以下原则,能够降低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

 

你可能感兴趣的:(加密和安全)