XSS攻击原理和防御措施

关于CSRF攻击可以看这篇文章。关于CSRF攻击的原理以及防御措施

跨站脚本攻击

跨站脚本攻击(Cross Site Scripting):攻击者通过在目标网站上注入恶意脚本,使之在用户的浏览器上运行。利用这些恶意脚本,攻击者可获取用户的敏感信息等,进而危害数据安全。

对用户造成的危害如:

  • 窃取Cookie
  • 监听用户行为,比如输入账号密码后直接发送到黑客服务器
  • 修改 DOM 伪造登录表单
  • 在页面中生成浮窗广告

XSS 的本质是:恶意代码未经过滤,与网站正常的代码混在一起;浏览器无法分辨哪些脚本是可信的,导致恶意脚本被执行。

XSS的类型

  • 存储型XSS:也叫“持久型”,攻击者将恶意代码提交到目标网站的数据库中,用户打开网站是,网站服务端将恶意代码从数据库中取出,拼接在HTML中返回浏览器,之后用户浏览器收到响应后解析执行混入其中的恶意代码,恶意代码窃取用户数据并发送到攻击者的网站,或者冒充用户行为,调用目标网站接口执行攻击者指定的操作。
    • 论坛发帖
    • 评论
    • 用户私信
  • 反射型XSS:也叫“非持久型”,攻击者事先制作好攻击链接,需要诱导欺骗用户自己去点击链接才能触发XSS代码(服务器中没有这样的页面和内容),一般容易出现在搜索页面。
    用户点击攻击链接将一段含有恶意代码的请求提交给 Web 服务器,Web 服务器接收到请求时,又将恶意代码反射给了浏览器端。用户浏览器接收到响应后解析执行,混在其中的恶意代码也被执行。
    • 常见于通过 URL 传递参数的功能,如网站搜索、跳转等。(由于需要用户主动打开恶意的 URL 才能生效,攻击者往往会结合多种手段诱导用户点击。)
  • DOM型:前端 JavaScript 代码不够严谨,把不可信的内容插入到了页面。
    举个例子:
<script>
  //该函数接受一个用户提供的 URL 并展示在页面
  function displayURL(url) {
    // URL 通过 innerHTML 获得,执行 JavaScript 代码
    document.getElementById('display').innerHTML = url;
  }
</script>

<!-- 用户的输入传递给 displayURL 函数 -->
<p>Enter a URL to display: <input type="text" id="user-input" /></p>
<button onclick="displayURL(document.getElementById('user-input').value)">
  Display URL
</button>

<!-- URL 在 div 中显示 -->
<div id="display"></div>

XSS防御的措施

  1. 对用户的输入数据进行过滤,编码等操作。

  2. 对cookie进行保护,设置为httpOnly,防止客户端通过document.cookie读取cookie(服务端设置)。

  3. 利用 CSP(内容安全策略)
    这里以设置 HTTP Header 来举例:
    只允许加载本站资源
    Content-Security-Policy: default-src 'self'
    只允许加载 HTTPS 协议图片
    Content-Security-Policy: img-src https://*
    通过CSP可以:

    • 限制加载其他域下的资源文件,这样即使黑客插入了一个 JavaScript 文件,这个 JavaScript 文件也是无法被加载的;
    • 禁止向第三方域提交数据,这样用户数据也不会外泄;
    • 禁止执行内联脚本和未授权的脚本
  4. 预防存储型和反射型XSS攻击

    • 改成纯前端渲染,把代码和数据分隔开
    • 对HTML做充分转义

vue中预防xss

  1. 输入过滤和验证
<template>
  <div>
    <input v-model="inputValue" v-filter>
  </div>
</template>

Vue.directive('filter', {
  bind: function(el, binding, vnode) {
    el.addEventListener('input', function() {
      let value = el.value;
      value = value.replace(/<[^>]*>|[\r\n\t]/gi, '');
      value = value.replace(/[&<>"]/gi, function(match) {
        switch (match) {
          case '&':
            return '&amp;';
          case '<':
            return '&lt;';
          case '>':
            return '&gt;';
          case '\"':
            return '&quot;';
        }
      });
      vnode.context[binding.expression] = value;
    });
  }
});
  1. 输出转义
<template>
  <div v-html="htmlString"></div>
</template>
export default {
  data() {
    return {
      htmlString: '<div>Hello & World!</div>'
    };
  }
}
  1. CSP(Content Security Policy)
    用vue-meta库来添加CSP策略,限制网页中可以加载的内容和脚本
    设置不同的源策略(如defaultSrc、scriptSrc、styleSrc等)来限制不同类型的资源的加载,如下设置了只允许加载本地资源和内联js脚本,禁止加载其他域名的脚本和资源。
import Vue from 'vue';
import VueMeta from 'vue-meta';
Vue.use(VueMeta, {
  keyName: 'metaInfo',
  attribute: 'data-vue-meta',
  ssrAttribute: 'data-vue-meta-server-rendered',
  tagIDKeyName: 'vmid',
  refreshOnceOnNavigation: true,
  contentSecurityPolicy: {
    defaultSrc: ["'self'"],
    scriptSrc: ["'self'", "'unsafe-inline'"],
    styleSrc: ["'self'", "'unsafe-inline'"],
    imgSrc: ["'self'"],
    connectSrc: ["'self'"],
    fontSrc: ["'self'"],
    objectSrc: ["'none'"],
    mediaSrc: ["'self'"]
  }
});
  1. HTTP-only Cookie
    在Vue.js中可以通过在服务器端设置HTTP-only标记来防止XSS攻击。当HTTP-only标记被设置时,浏览器只会在HTTP请求中发送cookie信息,而禁止使用JavaScript等脚本来读取或修改cookie。例如,在使用Express.js作为服务器端框架时,可以使用以下代码来设置HTTP-only标记:
const express = require('express');
const cookieParser = require('cookie-parser');
const app = express();
app.use(cookieParser());
app.get('/', function(req, res) {
  res.cookie('sessionId', '12345', { httpOnly: true });
  res.send('Hello World!');
});
  1. Sanitize HTML
    在Vue.js中可以使用DOMPurify库来过滤和清理用户输入的HTML代码,从而减少XSS攻击的风险。DOMPurify库可以检测和清理HTML代码中的恶意代码,包括JavaScript脚本、HTML注入、CSS注入、URL跳转等攻击方式。例如,在Vue.js中可以使用以下代码来过滤用户输入的HTML代码:
import DOMPurify from 'dompurify';
const dirtyHtml = '<script>alert("XSS Attack!");</script><a href="http://example.com">Link</a>';
const cleanHtml = DOMPurify.sanitize(dirtyHtml);
console.log(cleanHtml); // <a href="http://example.com">Link</a>
  1. Escape Output
    使用{{}}语法来显示动态内容,需要注意的是,需要对显示的内容进行转义
    在下面代码中,使用escape方法来转义输出的内容,使用正则表达式来匹配需要转义的字符,并使用替换函数来替换字符,从而实现转义输出的功能。
<template>
  <div>
    {{ escape(content) }}
  </div>
</template>
<script>
export default {
  data() {
    return {
      content: '<script>alert("XSS Attack!");</script>'
    }
  },
  methods: {
    escape(content) {
      return content.replace(/[<>"&]/g, function(match) {
        return {
          '<': '&lt;',
          '>': '&gt;',
          '"': '&quot;',
          '&': '&amp;'
        }[match];
      });
    }
  }
}
</script>

借鉴文章

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值