前端安全之 xss 攻击

什么是 xss?

XSS 攻击指通过巧妙的方法注入恶意指令代码到网页,使用户加载并执行攻击者恶意制造的代码。

危害有什么?

  1. 跳转到广告页面,页面注入广告等等。
  2. 导致公司域名被其他平台拉黑,从而使业务受损。
  3. 用户的财产受到威胁,他注入的代码可以在网页中任意请求接口。

注入代码

http://upcdn"'>\n\t\n

上面的代码是我们测试的时候使用的,接下来我们来分析一下这个代码主要用途。

  1. http://upcdn 这个字符串是用来伪装的。

  2. "'> 这两个就是为了截断当前字符串,然后闭合标签。

  3.  也是为了闭合标签,这个主要用在后台模板输出的时候。后台模板 velocity、freemarker 之类的。

  4.  就是引入一个js,这种方式比较常见。注入之后,攻击者只需要修改自己的文件,就可以更新了。
  5.  直接执行js代码
  6.  注入一个元素,用于展示一个异常块打乱布局。比如 vue 中的 v-html 不会执行 script 标签中的内容,但是会显示 svg 图片。
  7. \n\t\n 是为了测试后台模板输出的场景。

防护场景及方案

后台模板

  1. toHtml 主要用于输出在页面(标签中)中,将用户输入的内容进行编码比如 <转换为<

    • ${nickanme}
  2. toJS 主要用于输出在script标签中,这里需要防止打断js,比如处理成"'\n\"\'\\n
  3. toUrl 这里其实和 toHtml 场景很像,但是需要判断url基础格式。

    • https://
    • //lilnong.top
    • /static
    • ./static
    • ../static

jquery&原生js

  1. toHtml 场景。jquery中基本上都是拼接一下,然后 .html 输出一下。这里需要做的也是把用户输入的做一下实体编码转换。
  2. toUrl 场景。校验一下url,然后 toHtml 或者 encode 都可以。

vue

  1. toHtml 场景。v-html 这里需要注意一下,尽可能不要使用,因为会导致注入问题。也可以toHtml一下,但是没必要不是吗。
  2. toUrl 场景。:href 主要 javascript:alert(1);这种场景,做url校验就可以。
  3. toHtml 场景。使用原生的方法,vue 中非要 innerHTML的那些人。

常见问题

富文本场景

  1. 做文章那种,大量的标签,属性。这种一般需要后端处理。HTML Purifier
  2. 文字加表情,后者搜索高亮的场景。这种我们可以先执行toHtml,然后再匹配替换,最后在输出到页面即可。

换行符问题

有时我们在textarea中输入\n,渲染的时候空白符就被浏览器给吃了。针对这种情况,我们可以用下面的方案处理

  1. 通过 css 属性 white-space,或者 
     标签
  2. 一般人们是正则替换.replace(/\n/g,'
    )
    ,这种输出的时候万一里面有代码不就凉了吗。所以我们先 toHtml 然后在使用,这样可以防止注入问题。
  3. 其实 .innerText 可以自动把\n转换为
    ,你可以自己试试

代码实现

window.base = {
    toHtml: function (val) {
        if( typeof val != 'string' ) return '';
        var entityMap = {
            "&": "&",
            "<": "<",
            ">": ">",
            '"': '"',
            "'": ''',
            "/": '/'
        };
        return String(val).replace(/[&<>"'\/]/g, function (s) {
            return entityMap[s];
        });
    },
    toUrl: function (url) {
        if( typeof url != 'string' ) return '#';
        if(url.match(/^http/i)){
            return encodeURI(url)
        }
        return '#'
    },
};

你可能感兴趣的:(js基础/ES6+,其他类型)