Web前端开发网

fly63.com

首页 资源 工具 文章 教程 栏目
  • 关于我们
  • 广告合作
  • 网站投稿
  • 文章标签
  • 赞助一下
搜索

在线工具_工作生活好帮手

打造各种简单、易用、便捷的在线工具,网友无需注册和下载安装即可使用

点击查看

资源分类

AI智能 酷站推荐 招聘/兼职 框架/库 模块/管理 移动端UI框架 Web-UI框架 Js插件 Jquery插件 CSS相关 IDE环境 在线工具 图形动效 游戏框架 node相关 调试/测试 在线学习 社区/论坛 博客/团队 前端素材 图标/图库 建站资源 设计/灵感 IT资讯
提交资源 / 链接反馈

DOMPurify

分享
复制链接
新浪微博
QQ 好友

扫一扫分享

网站地址:https://cure53.de/purify
GitHub:https://github.com/cure53/DOMPurify
网站描述:一款专门用于防御XSS攻击的Js库
访问官网 GitHub

domPurify 是一个专业的html安全清理工具,专门用来防御跨站脚本(XSS)攻击。它就像一个严格的安检员,能够识别并移除HTML中的危险内容,只留下安全的代码。


核心特点

  • 超快速度:利用浏览器原生能力,性能优异

  • 全面防护:支持 HTML、MathML 和 SVG 清理

  • 广泛兼容:支持所有现代浏览器

  • 高度可配置:可以根据需求定制清理规则


快速开始

安装方式

通过 npm/yarn 安装:

npm install dompurify
# 或
yarn add dompurify

CDN 引入:

<script src="https://cdnjs.cloudflare.com/ajax/libs/dompurify/3.0.5/purify.min.js"></script>

基础使用方法

// 在表单提交时净化用户输入
import DOMPurify from 'dompurify';

function handleLogin() {
    const username = DOMPurify.sanitize(document.getElementById('username').value);
    const password = DOMPurify.sanitize(document.getElementById('password').value);
    
    // 现在可以安全地使用这些值了
    login(username, password);
}

// 净化用户输入的HTML内容
function displayUserContent(userInput) {
    const cleanHTML = DOMPurify.sanitize(userInput);
    document.getElementById('content').innerHTML = cleanHTML;
}


实际效果演示

看看 DOMPurify 如何清理危险代码:

// 危险的 HTML 输入
const dangerousInputs = [
    '<img src=x onerror=alert("XSS")>',
    '<svg><g/onload=alert("SVG攻击")></svg>',
    '<p>正常内容<iframe src="javascript:alert(1)">恶意部分</p>',
    '<a href="javascript:alert(\'点击劫持\')">点击我</a>'
];

// 净化后的安全结果
dangerousInputs.forEach(input => {
    const clean = DOMPurify.sanitize(input);
    console.log('输入:', input);
    console.log('输出:', clean);
    console.log('---');
});

/* 输出结果:
输入: <img src=x onerror=alert("XSS")>
输出: <img src="x">

输入: <svg><g/onload=alert("SVG攻击")></svg>
输出: <svg><g></g></svg>

输入: <p>正常内容<iframe src="javascript:alert(1)">恶意部分</p>
输出: <p>正常内容</p>

输入: <a href="javascript:alert('点击劫持')">点击我</a>
输出: <a>点击我</a>
*/


高级配置实战

1. 自定义允许的标签和属性

// 博客评论系统配置 - 只允许基本的格式标签
const blogCommentConfig = {
    ALLOWED_TAGS: ['p', 'br', 'strong', 'em', 'a', 'code'],
    ALLOWED_ATTR: ['href', 'title'],
    FORBID_TAGS: ['script', 'style', 'img', 'iframe'],
    FORBID_ATTR: ['style', 'class', 'onclick', 'onmouseover']
};

// 用户个人简介配置 - 允许更多样式
const userProfileConfig = {
    ALLOWED_TAGS: ['p', 'br', 'strong', 'em', 'a', 'img', 'ul', 'li'],
    ALLOWED_ATTR: ['href', 'src', 'alt', 'title'],
    ALLOWED_URI_REGEXP: /^(https?|ftp):/i
};

function sanitizeComment(userInput) {
    return DOMPurify.sanitize(userInput, blogCommentConfig);
}

function sanitizeProfile(userInput) {
    return DOMPurify.sanitize(userInput, userProfileConfig);
}

2. 处理富文本编辑器内容

// CKEditor 或 TinyMCE 内容净化
const richTextConfig = {
    ALLOWED_TAGS: [
        'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6',
        'strong', 'em', 'u', 's', 'blockquote', 'code',
        'pre', 'ul', 'ol', 'li', 'a', 'img', 'br', 'hr'
    ],
    ALLOWED_ATTR: [
        'href', 'title', 'src', 'alt', 'class',
        '>, '>// 允许自定义数据属性
    ],
    ALLOWED_URI_REGEXP: /^(https?|ftp|data):/i,
    FORBID_ATTR: ['style', 'onclick']
};

class RichTextProcessor {
    constructor() {
        this.config = richTextConfig;
    }
    
    // 处理编辑器内容
    processContent(htmlContent) {
        return DOMPurify.sanitize(htmlContent, this.config);
    }
    
    // 批量处理多个内容
    processMultiple(contents) {
        return contents.map(content => 
            DOMPurify.sanitize(content, this.config)
        );
    }
}

// 使用示例
const processor = new RichTextProcessor();
const userArticle = editor.getContent(); // 从富文本编辑器获取
const safeArticle = processor.processContent(userArticle);

3. 自定义钩子函数

// 移除所有外部图片,只允许内嵌base64图片
DOMPurify.addHook('beforeSanitizeAttributes', (node) => {
    if (node.tagName === 'IMG') {
        const src = node.getAttribute('src');
        if (src && !src.startsWith('data:')) {
            node.removeAttribute('src');
        }
    }
});

// 为所有外部链接添加 nofollow 和 target="_blank"
DOMPurify.addHook('afterSanitizeAttributes', (node) => {
    if (node.tagName === 'A') {
        const href = node.getAttribute('href');
        if (href && href.startsWith('http')) {
            node.setAttribute('rel', 'nofollow noopener');
            node.setAttribute('target', '_blank');
        }
    }
});


实际应用场景

场景1:用户评论系统

class CommentSystem {
    constructor() {
        this.config = {
            ALLOWED_TAGS: ['p', 'br', 'strong', 'em', 'a', 'code'],
            ALLOWED_ATTR: ['href'],
            ALLOWED_URI_REGEXP: /^https?:\/\/(www\.)?(example\.com|trusted-site\.org)/i,
            FORBID_TAGS: ['script', 'style', 'img']
        };
    }
    
    addComment(userInput, userName) {
        // 净化用户输入
        const cleanContent = DOMPurify.sanitize(userInput, this.config);
        
        // 创建安全的评论元素
        const commentElement = this.createCommentElement(cleanContent, userName);
        
        // 添加到页面
        document.getElementById('comments').appendChild(commentElement);
    }
    
    createCommentElement(content, userName) {
        const div = document.createElement('div');
        div.className = 'comment';
        div.innerHTML = `
            <div>
                <strong>${DOMPurify.sanitize(userName)}</strong>
            </div>
            <div>${content}</div>
        `;
        return div;
    }
}

场景2:消息通知系统

class NotificationSystem {
    constructor() {
        this.config = {
            ALLOWED_TAGS: ['strong', 'em', 'a'],
            ALLOWED_ATTR: ['href'],
            ALLOWED_URI_REGEXP: /^https?:\/\//i
        };
    }
    
    showNotification(message, type = 'info') {
        const cleanMessage = DOMPurify.sanitize(message, this.config);
        const notification = document.createElement('div');
        notification.className = `notification ${type}`;
        notification.innerHTML = cleanMessage;
        
        document.body.appendChild(notification);
        setTimeout(() => notification.remove(), 5000);
    }
}

// 使用示例
const notifier = new NotificationSystem();
notifier.showNotification('欢迎 <strong>新用户</strong>!点击<a href="/welcome">这里</a>查看指南。');

场景3:动态内容加载

class DynamicContentLoader {
    constructor() {
        this.config = {
            ALLOWED_TAGS: ['div', 'p', 'span', 'strong', 'em', 'a', 'img', 'br'],
            ALLOWED_ATTR: ['class', 'href', 'src', 'alt', 'title'],
            ALLOWED_URI_REGEXP: /^(https?|data):/i
        };
    }
    
    async loadUserGeneratedContent(userId) {
        try {
            const response = await fetch(`/api/user-content/${userId}`);
            const data = await response.json();
            
            // 净化用户生成的内容
            const cleanContent = DOMPurify.sanitize(data.content, this.config);
            
            // 安全地显示内容
            this.renderContent(cleanContent);
        } catch (error) {
            console.error('加载内容失败:', error);
        }
    }
    
    renderContent(cleanHTML) {
        const container = document.getElementById('user-content');
        container.innerHTML = cleanHTML;
    }
}


安全最佳实践

1. 防御层次化策略

class SecurityManager {
    constructor() {
        this.domPurifyConfig = {
            ALLOWED_TAGS: ['p', 'br', 'strong', 'em', 'a'],
            ALLOWED_ATTR: ['href'],
            ALLOWED_URI_REGEXP: /^https?:\/\//i
        };
    }
    
    // 多层验证
    validateAndSanitize(input, maxLength = 1000) {
        // 第一层:长度限制
        if (input.length > maxLength) {
            throw new Error('输入内容过长');
        }
        
        // 第二层:基础字符检查
        if (/[<>]/.test(input) && !/<[^>]*>/.test(input)) {
            throw new Error('包含危险字符');
        }
        
        // 第三层:DOMPurify 净化
        return DOMPurify.sanitize(input, this.domPurifyConfig);
    }
}

2. 错误处理和监控

class SafeDOMPurify {
    constructor(config = {}) {
        this.defaultConfig = {
            ALLOWED_TAGS: ['p', 'br', 'strong', 'em'],
            ALLOWED_ATTR: [],
            ...config
        };
    }
    
    safeSanitize(html, customConfig = {}) {
        try {
            const config = { ...this.defaultConfig, ...customConfig };
            const result = DOMPurify.sanitize(html, config);
            
            // 记录净化统计(生产环境中发送到监控系统)
            this.logSanitization(html, result);
            
            return result;
        } catch (error) {
            console.error('DOMPurify 处理失败:', error);
            // 返回空字符串作为安全降级
            return '';
        }
    }
    
    logSanitization(original, sanitized) {
        const stats = {
            originalLength: original.length,
            sanitizedLength: sanitized.length,
            reduction: ((original.length - sanitized.length) / original.length * 100).toFixed(2),
            timestamp: new Date().toISOString()
        };
        
        console.log('净化统计:', stats);
    }
}


性能优化建议

1. 批量处理

// 批量净化多个内容
function batchSanitize(contents, config) {
    return contents.map(content => 
        DOMPurify.sanitize(content, config)
    );
}

// 使用 Worker 处理大量内容
class DOMPurifyWorker {
    constructor() {
        this.worker = new Worker('dompurify-worker.js');
    }
    
    sanitizeInWorker(html, config) {
        return new Promise((resolve) => {
            this.worker.postMessage({ html, config });
            this.worker.onmessage = (e) => resolve(e.data);
        });
    }
}

2. 缓存配置

class OptimizedSanitizer {
    constructor() {
        this.configCache = new Map();
    }
    
    getConfig(profile) {
        if (!this.configCache.has(profile)) {
            const config = this.createConfig(profile);
            this.configCache.set(profile, config);
        }
        return this.configCache.get(profile);
    }
    
    createConfig(profile) {
        const profiles = {
            'comment': { ALLOWED_TAGS: ['p', 'br', 'strong', 'em'] },
            'article': { ALLOWED_TAGS: ['p', 'h1', 'h2', 'h3', 'strong', 'em', 'a', 'img'] },
            'minimal': { ALLOWED_TAGS: [] }
        };
        
        return profiles[profile] || profiles.minimal;
    }
}


总结

DOMPurify 是前端安全的重要防线,通过合理配置和使用,可以有效地防御 XSS 攻击。记住这些关键点:

  1. 始终净化用户输入:不要信任任何来自用户的内容

  2. 按需配置:根据具体场景设置合适的允许标签和属性

  3. 多层防御:结合其他安全措施,形成完整的防护体系

  4. 监控和测试:定期检查净化效果,确保安全策略有效

通过正确使用 DOMPurify,你可以大大提升网站的安全性,保护用户数据不受攻击。

仅供个人学习参考/导航指引使用,具体请以第三方网站说明为准,本站不提供任何专业建议。如果地址失效或描述有误,请联系站长反馈~感谢您的理解与支持!

链接: https://fly63.com/nav/4809

广告图片

more>>
相关栏目
layer
layer是一款口碑极佳的web弹层组件
点击进入 GitHub
iScroll.js
IScroll是移动页面上被使用的一款仿系统滚动插件。
官网 GitHub
wangEditor
基于javascript和css开发的 Web富文本编辑器
官网 GitHub
ueditor
由百度web前端研发部开发所见即所得富文本web编辑器
官网 GitHub
highlight
Highlight.js 是一个用 JavaScript 写的代码高亮插件,在客户端和服务端都能工作。
官网 GitHub
UglifyJS
一个js 解释器、最小化器、压缩器、美化器工具集
官网 GitHub
lozad.js
高性能,轻量级,可配置的懒加载图片工具
官网 GitHub
Sortable.js
简单灵活的 JavaScript 拖放排序插件
官网 GitHub
validate.js
表单提供了强大的验证功能,让客户端表单验证变得更简单
官网 GitHub
Draggin.js
一款兼容移动手机的js拖拽插件
官网 GitHub
lazysizes.js
响应式图像延迟加载JS插件【懒加载】
官网 GitHub
cropper.js
通过canvas实现图片裁剪
官网 GitHub
clipboard.js
浏览器中复制文本到剪贴板的插件,不需要Flash,仅仅2kb
官网 GitHub
siema
轻量级简单的纯 Js轮播插件
官网 GitHub
Mermrender
用于生成序列和UML图的RESTful渲染管道
官网 GitHub
Editor.js
JSON格式输出数据的富文本和媒体编辑器
官网 GitHub

手机预览

首页 技术导航 在线工具 技术文章 教程资源 AI工具集 前端库/框架 实用工具箱

Copyright © 2018 Web前端开发网提供免费在线工具、编程学习资源(教程/框架/库),内容以学习参考为主,助您解决各类实际问题,快速提升专业能力。