前端防范 XSS(跨站脚本攻击)

目录

一、防范措施

[1.layui util](#1.layui util)

核心转义的特殊字符

示例

2.js-xss.js库

安装

[1. Node.js 环境(npm/yarn)](#1. Node.js 环境(npm/yarn))

[2. 浏览器环境](#2. 浏览器环境)

[核心 API 基础使用](#核心 API 基础使用)

[1. 基础过滤(默认规则)](#1. 基础过滤(默认规则))

[2. 自定义过滤规则](#2. 自定义过滤规则)

(1)允许特定标签

(2)允许特定属性

(3)自定义标签处理

(4)自定义属性处理

(5)转义特定字符

常见场景示例

[1. 过滤用户输入的评论内容](#1. 过滤用户输入的评论内容)

[2. 允许特定富文本标签(如富文本编辑器内容)](#2. 允许特定富文本标签(如富文本编辑器内容))

注意事项

更多配置


XSS(跨站脚本攻击)是一种常见的网络攻击手段,它允许攻击者将恶意脚本注入到其他用户的浏览器中。XSS攻击通常发生在用户浏览网页时,攻击者通过在网站表单、评论区、URL参数等地方插入恶意脚本代码,当其他用户访问该页面时,这些脚本就会在用户的浏览器中执行。那该如何预防呢,一般是对输入框输入的内容数据进行验证和清理,确保不包含任何可执行的脚本代码。

一、防范措施

可自行封装一个防范XSS攻击的方法,这种较为自由,能根据项目需求自定义防范标准,当然也可以借用相关的工具库,更加方便,下面我为大家整理了相关工具的用法。

1.layui util

layui Util 提供的 layui.util.escape() 是核心的 XSS 防护方法,其核心作用是对 HTML 中的特殊字符进行转义处理,会将具有潜在危险的特殊字符转换为对应的 HTML 实体,从而阻止恶意脚本被浏览器解析执行,从根源上防范大部分反射型、存储型 XSS 攻击。

核心转义的特殊字符

该方法会针对性转义 HTML 中最具危险性的特殊字符,核心转义规则如下:

原始特殊字符 转义后的 HTML 实体 说明
< &lt; 小于号,HTML 标签开始标识
> &gt; 大于号,HTML 标签结束标识
" &quot; 双引号,属性值包裹标识
' &#39; 单引号,属性值包裹标识
& &amp; 和号,HTML 实体的起始标识

这些字符是构建 HTML 标签、属性的关键,恶意攻击者常通过注入包含这些字符的脚本(如 <script>alert('XSS')</script>)来实施攻击,转义后这些脚本会变成纯文本,无法被浏览器解析执行。

示例
javascript 复制代码
layui.use('util', function(){
  var util = layui.util;
  
  // 模拟用户输入的恶意内容(含XSS脚本)
  var maliciousContent = '<script>alert("XSS攻击");</script><a href="javascript:evil()">恶意链接</a>';
  
  // 使用escape方法进行XSS转义
  var safeContent = util.escape(maliciousContent);
  
  // 输出结果(已转为安全的HTML实体)
  console.log(safeContent);
  // 输出:&lt;script&gt;alert(&quot;XSS攻击&quot;);&lt;/script&gt;&lt;a href=&quot;javascript:evil()&quot;&gt;恶意链接&lt;/a&gt;
  
  // 将转义后的内容插入页面(仅显示为纯文本,不会执行脚本)
  document.getElementById('content').innerText = safeContent;
});

2.js-xss.js库

js-xss 是一个用于防范 XSS(跨站脚本攻击)的 JavaScript 库,能够过滤 HTML 字符串、移除危险标签 / 属性,确保输出的 HTML 安全可渲染。以下是 js-xss 的详细用法,包括安装、基础使用、自定义规则、常见场景等。

安装
1. Node.js 环境(npm/yarn)
javascript 复制代码
# npm
npm install xss --save

# yarn
yarn add xss
2. 浏览器环境

直接引入 CDN 或本地文件:

html 复制代码
<!-- CDN -->
<script src="https://cdn.jsdelivr.net/npm/xss/dist/xss.min.js"></script>

<!-- 本地(下载后) -->
<script src="path/to/xss.min.js"></script>
核心 API 基础使用

js-xss 的核心是 xss() 函数,传入需要过滤的字符串,返回安全的 HTML。

1. 基础过滤(默认规则)

默认规则会移除所有危险标签(如 <script><iframe>)和危险属性(如 onclickonload),保留常规标签(如 <div><p>)。

javascript 复制代码
// Node.js 环境
const xss = require('xss');

// 浏览器环境直接使用全局变量 xss

// 待过滤的危险字符串
const dangerousHtml = `
  <div onclick="alert('xss')">点击我</div>
  <script>stealData()</script>
  <img src="x" onerror="alert(1)">
`;

// 过滤
const safeHtml = xss(dangerousHtml);

console.log(safeHtml);
// 输出(危险内容被移除):
// <div>点击我</div>
// <img src="x">
2. 自定义过滤规则

通过配置选项自定义规则,满足个性化需求(如允许特定标签 / 属性、自定义标签处理逻辑)。

(1)允许特定标签
javascript 复制代码
const safeHtml = xss(dangerousHtml, {
  // 白名单:仅允许 div、p、img 标签(默认白名单包含大部分常规标签)
  whiteList: {
    div: [], // [] 表示允许该标签,但不允许任何属性
    p: ['class'], // 允许 p 标签的 class 属性
    img: ['src', 'alt'] // 允许 img 标签的 src、alt 属性
  }
});
(2)允许特定属性
javascript 复制代码
const html = '<div class="test" onclick="alert(1)" data-id="123">内容</div>';
const safeHtml = xss(html, {
  whiteList: {
    div: ['class', 'data-id'] // 允许 div 的 class 和 data-id 属性,移除 onclick
  }
});
console.log(safeHtml);
// 输出:<div class="test" data-id="123">内容</div>
(3)自定义标签处理

通过 onTag 钩子自定义标签的过滤逻辑:

javascript 复制代码
const safeHtml = xss(dangerousHtml, {
  onTag: function(tag, html, options) {
    // 禁止所有 h1 标签,直接返回空
    if (tag === 'h1') return '';
    // 其他标签按默认规则处理
    return undefined;
  }
});
(4)自定义属性处理

通过 onTagAttr 钩子自定义属性的过滤逻辑:

javascript 复制代码
const html = '<a href="javascript:alert(1)">链接</a>';
const safeHtml = xss(html, {
  onTagAttr: function(tag, name, value, isWhiteAttr) {
    // 处理 a 标签的 href 属性,过滤 javascript: 伪协议
    if (tag === 'a' && name === 'href') {
      if (value.startsWith('javascript:')) {
        return 'href="#invalid"'; // 替换为无效链接
      }
    }
    // 其他属性按默认规则处理
    return isWhiteAttr ? `${name}="${xss.escapeAttrValue(value)}"` : '';
  }
});
console.log(safeHtml);
// 输出:<a href="#invalid">链接</a>
(5)转义特定字符

默认会转义 <>&"' 等字符,也可自定义转义规则:

javascript 复制代码
const safeHtml = xss('<p>hello & world</p>', {
  escapeHtml: function(html) {
    // 自定义转义:仅转义 & 和 <
    return html.replace(/&/g, '&amp;').replace(/</g, '&lt;');
  }
});
console.log(safeHtml);
// 输出:<p>hello &amp; world</p>
常见场景示例
1. 过滤用户输入的评论内容
javascript 复制代码
// 假设用户提交的评论包含危险代码
const userComment = `
  <p>我的评论</p>
  <script>偷取cookie</script>
  <img src=x onerror="alert('xss')">
`;

// 过滤后渲染
const safeComment = xss(userComment, {
  whiteList: {
    p: ['class'],
    img: ['src', 'alt'] // 仅允许 img 的 src 和 alt 属性
  }
});

// 插入到页面
document.getElementById('comment').innerHTML = safeComment;
2. 允许特定富文本标签(如富文本编辑器内容)
javascript 复制代码
// 富文本允许的标签和属性
const richTextWhiteList = {
  h1: ['class'],
  h2: ['class'],
  p: ['class', 'style'],
  a: ['href', 'target', 'class'],
  img: ['src', 'alt', 'class', 'width', 'height'],
  strong: [],
  em: []
};

const richText = '<p style="color: red">富文本内容<a href="javascript:alert(1)">危险链接</a></p>';
const safeRichText = xss(richText, {
  whiteList: richTextWhiteList,
  // 允许 style 属性的特定值(需配合 onTagAttr 过滤)
  onTagAttr: function(tag, name, value) {
    if (tag === 'p' && name === 'style') {
      // 仅允许 color 样式
      if (/^color:\s*[a-zA-Z0-9#]+;?$/.test(value)) {
        return `style="${value}"`;
      }
      return '';
    }
    if (tag === 'a' && name === 'href') {
      // 过滤 a 标签的 javascript: 伪协议
      if (value.startsWith('javascript:')) {
        return 'href="#"';
      }
      return `href="${value}"`;
    }
    return `${name}="${value}"`;
  }
});
注意事项
  1. 不要完全依赖默认规则:根据业务场景自定义白名单,避免允许不必要的标签 / 属性。
  2. 富文本处理需谨慎:富文本编辑器可能允许更多标签,需精细化配置白名单和属性过滤。
  3. 服务端 + 客户端双重过滤:客户端过滤提升用户体验,服务端过滤是最后一道防线(防止绕过客户端过滤)。
  4. 特殊场景例外:如果需要允许部分安全的脚本(如第三方插件),需通过严格的白名单和校验,避免直接放行。
更多配置

js-xss 的完整配置项可参考官方文档:js-xss,核心配置包括:

  • whiteList:标签白名单(默认值参考源码)。
  • onTag:标签处理钩子。
  • onTagAttr:属性处理钩子。
  • onIgnoreTag:忽略标签时的钩子。
  • onIgnoreTagAttr:忽略属性时的钩子。
  • escapeHtml:自定义转义函数。
  • safeAttrValue:是否过滤属性值中的危险内容。

通过灵活配置,js-xss 可适配绝大多数 XSS 防护场景,是前端 / Node.js 中防范 XSS 的较为推荐的工具之一。

前端虽有xss防护,但是主要还需有后端的一起配合,

不要仅依赖「前端过滤」:攻击者可通过 Postman 等工具直接请求接口,后端必须过滤。

相关推荐
Rysxt_2 小时前
Vue 3 项目核心:main.ts 文件的作用与配置详解
前端·javascript·vue.js
就叫飞六吧2 小时前
基于spring web实现简单分片上传demo
java·前端·spring
AAA阿giao2 小时前
拼乐高式开发:深入剖析 React 组件通信、弹窗设计与样式管理
开发语言·前端·javascript·react.js·前端框架·props·components
lvbinemail2 小时前
svn的web管理后台服务svnWebUI
运维·前端·svn·jar
Violet_YSWY2 小时前
Promise 讲解
前端
软件开发技术深度爱好者2 小时前
数学公式生成器HTML版
前端·html
Marshmallowc2 小时前
CSS 布局原理:为何“负边距”是栅格系统的基石?
前端·css·面试
Rysxt_3 小时前
Vue 3 项目核心:App.vue 文件的作用与配置详解
前端·javascript·vue.js
洛阳纸贵3 小时前
JAVA高级工程师--Maven父子关系专题
java·前端·maven