目录
[1.layui util](#1.layui util)
[1. Node.js 环境(npm/yarn)](#1. Node.js 环境(npm/yarn))
[2. 浏览器环境](#2. 浏览器环境)
[核心 API 基础使用](#核心 API 基础使用)
[1. 基础过滤(默认规则)](#1. 基础过滤(默认规则))
[2. 自定义过滤规则](#2. 自定义过滤规则)
[1. 过滤用户输入的评论内容](#1. 过滤用户输入的评论内容)
[2. 允许特定富文本标签(如富文本编辑器内容)](#2. 允许特定富文本标签(如富文本编辑器内容))
XSS(跨站脚本攻击)是一种常见的网络攻击手段,它允许攻击者将恶意脚本注入到其他用户的浏览器中。XSS攻击通常发生在用户浏览网页时,攻击者通过在网站表单、评论区、URL参数等地方插入恶意脚本代码,当其他用户访问该页面时,这些脚本就会在用户的浏览器中执行。那该如何预防呢,一般是对输入框输入的内容数据进行验证和清理,确保不包含任何可执行的脚本代码。
一、防范措施
可自行封装一个防范XSS攻击的方法,这种较为自由,能根据项目需求自定义防范标准,当然也可以借用相关的工具库,更加方便,下面我为大家整理了相关工具的用法。
1.layui util
layui Util 提供的 layui.util.escape() 是核心的 XSS 防护方法,其核心作用是对 HTML 中的特殊字符进行转义处理,会将具有潜在危险的特殊字符转换为对应的 HTML 实体,从而阻止恶意脚本被浏览器解析执行,从根源上防范大部分反射型、存储型 XSS 攻击。
核心转义的特殊字符
该方法会针对性转义 HTML 中最具危险性的特殊字符,核心转义规则如下:
| 原始特殊字符 | 转义后的 HTML 实体 | 说明 |
|---|---|---|
< |
< |
小于号,HTML 标签开始标识 |
> |
> |
大于号,HTML 标签结束标识 |
" |
" |
双引号,属性值包裹标识 |
' |
' |
单引号,属性值包裹标识 |
& |
& |
和号,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);
// 输出:<script>alert("XSS攻击");</script><a href="javascript:evil()">恶意链接</a>
// 将转义后的内容插入页面(仅显示为纯文本,不会执行脚本)
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>)和危险属性(如 onclick、onload),保留常规标签(如 <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, '&').replace(/</g, '<');
}
});
console.log(safeHtml);
// 输出:<p>hello & 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}"`;
}
});
注意事项
- 不要完全依赖默认规则:根据业务场景自定义白名单,避免允许不必要的标签 / 属性。
- 富文本处理需谨慎:富文本编辑器可能允许更多标签,需精细化配置白名单和属性过滤。
- 服务端 + 客户端双重过滤:客户端过滤提升用户体验,服务端过滤是最后一道防线(防止绕过客户端过滤)。
- 特殊场景例外:如果需要允许部分安全的脚本(如第三方插件),需通过严格的白名单和校验,避免直接放行。
更多配置
js-xss 的完整配置项可参考官方文档:js-xss,核心配置包括:
whiteList:标签白名单(默认值参考源码)。onTag:标签处理钩子。onTagAttr:属性处理钩子。onIgnoreTag:忽略标签时的钩子。onIgnoreTagAttr:忽略属性时的钩子。escapeHtml:自定义转义函数。safeAttrValue:是否过滤属性值中的危险内容。
通过灵活配置,js-xss 可适配绝大多数 XSS 防护场景,是前端 / Node.js 中防范 XSS 的较为推荐的工具之一。
前端虽有xss防护,但是主要还需有后端的一起配合,
不要仅依赖「前端过滤」:攻击者可通过 Postman 等工具直接请求接口,后端必须过滤。