Fork me on GitHub

XSS攻击 知识学习

参考文章: web安全之XSS攻击原理及防范
啥叫XSS攻击:
XSS 即(Cross Site Scripting)中文名称为:跨站脚本攻击。重点是脚本攻击,其原理为在web页面中会插入一些恶意的script代码。当用户浏览该页面的时候,那么嵌入到web页面中script代码会执行,因此会达到恶意攻击用户的目的。
XSS攻击的几种类型:
反射型,DOM-based型(两个为非持久性攻击);存储型(持久性XSS攻击)。

反射型:(主要是恶意链接)
反射性xss一般指攻击者通过特定的方式来诱惑受害者去访问一个包含恶意代码的URL。当受害者点击恶意链接url的时候,恶意代码会直接在受害者的主机上的浏览器执行。
这种攻击方式的注入代码是从目标服务器通过错误信息,搜索结果等方式反射回来的,其是一次性的。比如:攻击者通过电子邮件等方式将包含注入脚本的恶意链接发送给受害者,当受害者点击该链接的时候,注入脚本被传输到目标服务器上,然后服务器将注入脚本 "反射"到受害者的浏览器上,从而浏览器就执行了该脚本,常见的反射性XSS为 恶意链接 。
反射型XSS的攻击步骤如下:
1. 攻击者在url后面的参数中加入恶意攻击代码。
2. 当用户打开带有恶意代码的URL的时候,网站服务端将恶意代码从URL中取出,拼接在html中并且返回给浏览器端。
3. 用户浏览器接收到响应后执行解析,其中的恶意代码也会被执行到。
**4. **攻击者通过恶意代码来窃取到用户数据并发送到攻击者的网站。攻击者会获取到比如cookie等信息,然后使用该信息来冒充合法用户的行为,调用目标网站接口执行攻击等操作。

存储型:(主要是存入数据库的内容)
将恶意代码上传或存储到服务器中,下次只要受害者浏览包含此恶意代码的页面就会执行恶意代码。
比如一个博客网站,攻击者在上面发布了一篇文章,内容是如下: 如果没有对该文章进行任何处理的话,直接存入到数据库中,那么下一次当其他用户访问该文章的时候,服务器会从数据库中读取后然后响应给客户端,那么浏览器就会执行这段脚本,然后攻击者就会获取到用户的cookie,然后会把cookie发送到攻击者的服务器上了。
存储型XSS的攻击步骤如下:
1. 攻击者将恶意代码提交到目标网站数据库中。
2. 用户打开目标网站时,网站服务器将恶意代码从数据库中取出,然后拼接到html中返回给浏览器中。
3. 用户浏览器接收到响应后解析执行,那么其中的恶意代码也会被执行。
**4. **那么恶意代码执行后,就能获取到用户数据,比如上面的cookie等信息,那么把该cookie发送到攻击者网站中,那么攻击者拿到该
cookie然后会冒充该用户的行为,调用目标网站接口等违法操作。

DOM-based型:(主要是本地客户端写入的dom数据在本地执行了)
DOM型XSS的攻击步骤如下:
**1. **攻击者构造出特殊的URL、在其中可能包含恶意代码。
2. 用户打开带有恶意代码的URL。
3. 用户浏览器收到响应后解析执行。前端使用js取出url中的恶意代码并执行。
4. 执行时,恶意代码窃取用户数据并发送到攻击者的网站中,那么攻击者网站拿到这些数据去冒充用户的行为操作。调用目标网站接口执行攻击者一些操作。

XSS攻击防范:
针对Cookie:
在服务器端设置cookie的时候设置 http-only, 这样就可以防止用户通过JS获取cookie。对cookie的读写或发送一般有如下字段进行设置:
http-only: 只允许http或https请求读取cookie、JS代码是无法读取cookie的(document.cookie会显示http-only的cookie项被自动过滤掉)。发送请求时自动发送cookie.
secure-only: 只允许https请求读取,发送请求时自动发送cookie。
host-only: 只允许主机域名与domain设置完成一致的网站才能访问该cookie。

X-XSS-Protection设置
目前该属性被所有的主流浏览器默认开启XSS保护。该参数是设置在响应头中目的是用来防范XSS攻击的。它有如下几种配置:
值有如下几种:默认为1.
0:禁用XSS保护。
1:启用XSS保护。
1;mode=block; 启用xss保护,并且在检查到XSS攻击时,停止渲染页面。

XSS防御HTML编码
对不信任的内容放入div或者span标签内前需要对内容进行HTML编码转义,防止包含非法字符:

// 使用正则表达式实现html编码(解码将replace后的 / /g 中的内容换位置)
    function htmlEncodeByRegExp(str) {
      var s = '';
      if (str.length === 0) {
        return s;
      }
      return (s + str)
        .replace(/&/g, "&")
        .replace(/</g, "&lt;")
        .replace(/>/g, "&gt;")
        .replace(/ /g, "&nbsp;")
        .replace(/\'/g, "&#39")
        .replace(/\"/g, "&quot;")
        .replace(/\//g, '&#x2F;');
    }

XSS 防御HTML Attribute(属性)编码
和HTML编码一样,html中的属性也要进行编码,比如 <.input name="name"/>这样的,name是input的属性,因此在html解析时,会对name属性进行编码,因为假如{name} 的值为:" " onclick="alert('属性XSS')" " " 此时input的name属性就被注入恶意代码了。
因此需要对HTML属性的值进行编码:

function encodeForHTMLAttibute(str) {
      let encoded = '';
      for(let i = 0; i < str.length; i++) {
        let ch = hex = str[i];
        if (!/[A-Za-z0-9]/.test(str[i]) && str.charCodeAt(i) < 256) {
          hex = '&#x' + ch.charCodeAt(0).toString(16) + ';';
        }
        encoded += hex;
      }
      return encoded;
   };

XSS防御之javascript编码

// 使用正则表达式实现JavaScript编码
    function encodeForJavascript(str) {
      let encoded = '';
      for(let i = 0; i < str.length; i++) {
        let cc = hex = str[i];
        if (!/[A-Za-z0-9]/.test(str[i]) && str.charCodeAt(i) < 256) {
          hex = '\\x' + cc.charCodeAt().toString(16);
        }
        encoded += hex;
      }
      return encoded;
    };

XSS 防御之 URL 编码
将不可信数据作为 URL 参数值时需要对参数进行encodeURIComponent URL 编码

function encodeForURL(str){
  return encodeURIComponent(str);
};

XSS 防御之 CSS 编码
将不可信数据作为 CSS 时进行 CSS 编码

<div style="background-image: url(javascript:alert('xss'));"></div>
<style>body{background-image: url("javascript:alert('xss')");}</style>
function encodeForCSS (attr, str){
  let encoded = '';
  for (let i = 0; i < str.length; i++) {
    let ch = str.charAt(i);
    if (!ch.match(/[a-zA-Z0-9]/) {
      let hex = str.charCodeAt(i).toString(16);
      let pad = '000000'.substr((hex.length));
      encoded += '\\' + pad + hex;
    } else {
      encoded += ch;
    }
  }
  return encoded;
};

开启CSP网页安全政策防止XSS攻击
Content-Security-Policy(CSP) 中文的意思是 网页安全政策,
我们只需要在meta属性中设置下即可:如下代码:
<meta http-equiv="Content-Security-Policy" content="">
比如如下的列子:

<meta http-equiv="Content-Security-Policy" content="
default-src http: https:  *.xxx.com 'self' 'unsafe-inline' ;
style-src 'self' 'unsafe-inline' *.yyy.com;
script-src 'self' 'unsafe-inline' 'unsafe-eval' ;
">

默认设置(default-src):信任 http ,https协议资源,信任当前域名资源,信任符合.xxx.com的域名资源CSS设置(style-src):信任当前域名资源,允许内嵌的CSS资源,信任来自.yyy.com下的CSS资源。
JS设置(script-src):信任当前域名资源,允许内嵌的JS执行,允许将字符串当作代码执行

有如下类别
default-src 给下面所有的规则设定一个默认值
script-src 外部脚本
style-src 样式表
img-src 图像
media-src 媒体文件(音频和视频)
font-src 字体文件
object-src 插件(比如 Flash)
child-src 框架
frame-ancestors 嵌入的外部资源(比如、<.iframe>、和)
connect-src HTTP 连接(通过 XHR、WebSockets、EventSource等)
worker-src worker脚本
manifest-src manifest 文件
script-src有如下属性值:
unsafe-inline 允许执行页面内嵌的

posted @ 2021-04-08 16:43  madman98  阅读(335)  评论(0编辑  收藏  举报