Web 安全漏洞之 XSS 攻击

简介:

14f0b3e4f513d868daf4fc3980b31adcfca73d11

编者说:作为JS系工程师接触最多的漏洞我想就是 XSS 漏洞了,然鹅并不是所有的同学对其都有一个清晰的认识。今天我们请来了@卢士杰 同学为我们分享他眼中的 XSS 漏洞攻击,希望能帮助到大家。

什么是 XSS 攻击

XSS(Cross-Site Scripting)又称跨站脚本,XSS的重点不在于跨站点,而是在于脚本的执行。XSS是一种经常出现在 Web 应用程序中的计算机安全漏洞,是由于 Web 应用程序对用户的输入过滤不足而产生的。

常见的 XSS 攻击有三种:反射型、DOM-based 型、存储型。 其中反射型、DOM-based 型可以归类为非持久型 XSS 攻击,存储型归类为持久型 XSS 攻击。

1.反射型

反射型 XSS 一般是攻击者通过特定手法(如电子邮件),诱使用户去访问一个包含恶意代码的 URL,当受害者点击这些专门设计的链接的时候,恶意代码会直接在受害者主机上的浏览器执行。

对于访问者而言是一次性的,具体表现在我们把我们的恶意脚本通过 URL 的方式传递给了服务器,而服务器则只是不加处理的把脚本“反射”回访问者的浏览器而使访问者的浏览器执行相应的脚本。反射型 XSS 的触发有后端的参与,要避免反射性 XSS,必须需要后端的协调,后端解析前端的数据时首先做相关的字串检测和转义处理。

此类 XSS 通常出现在网站的搜索栏、用户登录口等地方,常用来窃取客户端 Cookies 或进行钓鱼欺骗。

整个攻击过程大约如下:

2ac22c87c2a04f4c24154d838c8bc3bf734321b6

2.DOM-based 型

客户端的脚本程序可以动态地检查和修改页面内容,而不依赖于服务器端的数据。例如客户端如从 URL 中提取数据并在本地执行,如果用户在客户端输入的数据包含了恶意的 JavaScript 脚本,而这些脚本没有经过适当的过滤和消毒,那么应用程序就可能受到 DOM-based XSS 攻击。需要特别注意以下的用户输入源 document.URL、 location.hash、 location.search、 document.referrer 等。

整个攻击过程大约如下:

1f8c250d23450b3dc4ca285aca59f87d3c649090

3.存储型

攻击者事先将恶意代码上传或储存到漏洞服务器中,只要受害者浏览包含此恶意代码的页面就会执行恶意代码。这就意味着只要访问了这个页面的访客,都有可能会执行这段恶意脚本,因此储存型XSS的危害会更大。

存储型 XSS 一般出现在网站留言、评论、博客日志等交互处,恶意脚本存储到客户端或者服务端的数据库中。

整个攻击过程大约如下:

a2bc00c873fbb510de0e42f16db32ec7149c0ea6

XSS 攻击的危害

XSS 可以导致:

1. 攻击劫持访问;
2. 盗用 cookie 实现无密码登录;
3. 配合 csrf 攻击完成恶意请求;
4. 使用 js 或 css 破坏页面正常的结构与样式等;

防御方法

1. XSS 防御之 HTML 编码

应用范围:将不可信数据放入到 HTML 标签内(例如div、span等)的时候进行HTML编码。

编码规则:将 & < > " ' / 转义为实体字符(或者十进制、十六进制)。

示例代码:

 
  1.  function encodeForHTML(str, kwargs){

  2.    return ('' + str)

  3.      .replace(/&/g, '&')

  4.      .replace(/</g, '<')     // DEC=> < HEX=> < Entity=> <

  5.      .replace(/>/g, '>')

  6.      .replace(/"/g, '"')

  7.      .replace(/'/g, ''')   // ' 不推荐,因为它不在HTML规范中

  8.      .replace(/\//g, '/');

  9.  };

HTML 有三种编码表现方式:十进制、十六进制、命名实体。例如小于号(<)可以编码为 "十进制> <", "十六进制=> <", "命名实体=> <" 三种方式。对于单引号(')由于实体字符编码方式不在 HTML 规范中,所以此处使用了十六进制编码。

2. XSS 防御之 HTML Attribute 编码

应用范围:将不可信数据放入 HTML 属性时(不含src、href、style 和事件处理属性),进行 HTML Attribute 编码

编码规则:除了字母数字字符以外,使用 HH;(或者可用的命名实体)格式来转义ASCII值小于256所有的字符

示例代码:

 
  1.  function encodeForHTMLAttibute(str, kwargs){

  2.    let encoded = '';

  3.    for(let i = 0; i < str.length; i++) {

  4.      let ch = hex = str[i];

  5.      if (!/[A-Za-z0-9]/.test(str[i]) && str.charCodeAt(i) < 256) {

  6.        hex = '&#x' + ch.charCodeAt(0).toString(16) + ';';

  7.      }

  8.      encoded += hex;

  9.    }

  10.    return encoded;

  11.  };

3. XSS 防御之 JavaScript 编码

作用范围:将不可信数据放入事件处理属性、JavaScirpt值时进行 JavaScript 编码

编码规则:除字母数字字符外,请使用xHH格式转义ASCII码小于256的所有字符

示例代码:

 
  1.  function encodeForJavascript(str, kwargs) {

  2.    let encoded = '';

  3.    for(let i = 0; i < str.length; i++) {

  4.      let cc = hex = str[i];

  5.      if (!/[A-Za-z0-9]/.test(str[i]) && str.charCodeAt(i) < 256) {

  6.        hex = '\\x' + cc.charCodeAt().toString(16);

  7.      }

  8.      encoded += hex;

  9.    }

  10.    return encoded;

  11.  };

4. XSS 防御之 URL 编码

作用范围:将不可信数据作为 URL 参数值时需要对参数进行 URL 编码

编码规则:将参数值进行 encodeURIComponent 编码

示例代码:

 
  1.  function encodeForURL(str, kwargs){

  2.    return encodeURIComponent(str);

  3.  };

5. XSS 防御之 CSS 编码

作用范围:将不可信数据作为 CSS 时进行 CSS 编码

编码规则:除了字母数字字符以外,使用XXXXXX格式来转义ASCII值小于256的所有字符

示例代码:

 
  1.  function encodeForCSS (attr, str, kwargs){

  2.    let encoded = '';

  3.    for (let i = 0; i < str.length; i++) {

  4.      let ch = str.charAt(i);

  5.      if (!ch.match(/[a-zA-Z0-9]/) {

  6.        let hex = str.charCodeAt(i).toString(16);

  7.        let pad = '000000'.substr((hex.length));

  8.        encoded += '\\' + pad + hex;

  9.      } else {

  10.        encoded += ch;

  11.      }

  12.    }

  13.    return encoded;

  14.  };

后记

在任何时候用户的输入都是不可信的。对于 HTTP 参数,理论上都要进行验证,例如某个字段是枚举类型,其就不应该出现枚举以为的值;对于不可信数据的输出要进行相应的编码;此外 httpOnly、 CSP、 X-XSS-Protection、 Secure Cookie等也可以起到有效的防护。

XSS 漏洞有时比较难发现,所幸当下React、Vue等框架都从框架层面引入了 XSS 防御机制,一定程度上解放了我们的双手。
但是作为开发人员依然要了解 XSS 基本知识、于细节处避免制造 XSS 漏洞。框架是辅助,我们仍需以人为本,规范开发习惯,提高 Web 前端安全意识。

参考文档

 ●  http://www.qa-knowhow.com/?p=1467 
 ●  https://brajeshwar.github.io/entities/ 
 ●  https://excess-xss.com/ 

 ●  https://github.com/chrisisbeef/jquery-encoder


原文发布时间为:2018-11-23

本文来自云栖社区合作伙伴“前端大学”,了解相关信息可以关注“前端大学”。


相关文章
|
1月前
|
JavaScript 安全 前端开发
js开发:请解释什么是XSS攻击和CSRF攻击,并说明如何防范这些攻击。
XSS和CSRF是两种常见的Web安全威胁。XSS攻击通过注入恶意脚本盗取用户信息或控制账户,防范措施包括输入验证、内容编码、HTTPOnly Cookie和CSP。CSRF攻击则诱使用户执行未经授权操作,防范手段有CSRF Tokens、双重验证、Referer检查和SameSite Cookie属性。开发者应采取这些防御措施并定期进行安全审计以增强应用安全性。
21 0
|
2月前
|
存储 安全 JavaScript
26、XSS漏洞介绍
26、XSS漏洞介绍
19 0
|
2天前
|
缓存 安全 JavaScript
前端安全:Vue应用中防范XSS和CSRF攻击
【4月更文挑战第23天】本文探讨了在Vue应用中防范XSS和CSRF攻击的重要性。XSS攻击通过注入恶意脚本威胁用户数据,而CSRF则利用用户身份发起非授权请求。防范措施包括:对输入内容转义、使用CSP、选择安全的库;采用Anti-CSRF令牌、同源策略和POST请求对抗CSRF;并实施代码审查、更新依赖及教育团队成员。通过这些实践,可提升Vue应用的安全性,抵御潜在攻击。
|
3天前
|
SQL 存储 前端开发
< 今日份知识点:web常见的攻击方式(网络攻击)有哪些?如何预防?如何防御呢 ? >
网络安全威胁日益严重,2017年的永恒之蓝勒索病毒事件揭示了网络攻击的破坏力。为了防御Web攻击,了解攻击类型至关重要。Web攻击包括XSS、CSRF和SQL注入等,其中XSS分为存储型、反射型和DOM型,允许攻击者通过注入恶意代码窃取用户信息。防止XSS攻击的方法包括输入验证、内容转义和避免浏览器执行恶意代码。CSRF攻击则伪装成用户执行操作,防范措施包括同源策略和CSRF Token验证。SQL注入则通过恶意SQL语句获取数据,预防手段包括输入验证和使用预编译语句。面对网络威胁,加强安全意识和实施防御策略是必要的。
|
10天前
|
安全 JavaScript Go
跨站脚本攻击(XSS)防护在Django中的应用
【4月更文挑战第15天】本文介绍了Django如何防范XSS攻击。Django模板引擎自动转义HTML以防止恶意脚本,提供`mark_safe`函数和CSRF防护。此外,建议开发者验证清理用户输入、使用内容安全策略、更新库以及遵循安全编码实践来增强防护。通过这些措施,开发者能构建更安全的Web应用。
|
1月前
|
安全 JavaScript 前端开发
Low 级别反射型 XSS 演示(附链接)
Low 级别反射型 XSS 演示(附链接)
19 0
|
1月前
|
存储 JavaScript 前端开发
DOM 型 XSS 演示(附链接)
DOM 型 XSS 演示(附链接)
70 0
|
1月前
|
存储 前端开发 JavaScript
存储型 XSS 攻击演示(附链接)
存储型 XSS 攻击演示(附链接)
92 0
|
1月前
|
存储 前端开发 JavaScript
反射型 XSS 攻击演示(附链接)
反射型 XSS 攻击演示(附链接)
139 0
|
2月前
|
SQL 安全 Java
Java Web安全性:常见的漏洞及防护措施
Java Web安全性:常见的漏洞及防护措施
146 0