JavaScript系列(26)--安全编程实践详解

news2025/1/15 14:21:57

JavaScript安全编程实践详解 🔒

今天,让我们深入探讨JavaScript的安全编程实践。在当今的网络环境中,安全性已经成为开发者必须重点关注的领域。

安全编程基础 🌟

💡 小知识:JavaScript安全编程涉及多个方面,包括XSS防护、CSRF防御、输入验证、安全存储、安全通信等。通过采用正确的安全实践,我们可以有效防范常见的安全威胁。

XSS防护实践 🛡️

// 1. HTML转义工具
class HTMLEscaper {
    static escapeMap = {
        '&': '&',
        '<': '&lt;',
        '>': '&gt;',
        '"': '&quot;',
        "'": '&#x27;',
        '/': '&#x2F;'
    };
    
    static escape(str) {
        return str.replace(/[&<>"'/]/g, char => this.escapeMap[char]);
    }
    
    static createSafeHTML(unsafeHTML) {
        const div = document.createElement('div');
        div.textContent = unsafeHTML;
        return div.innerHTML;
    }
}

// 2. XSS防护包装器
class XSSProtector {
    constructor() {
        this.sanitizer = new DOMPurify();
    }
    
    // 安全地设置HTML内容
    setHTML(element, content) {
        element.innerHTML = this.sanitizer.sanitize(content, {
            ALLOWED_TAGS: ['p', 'span', 'b', 'i', 'em', 'strong'],
            ALLOWED_ATTR: ['class', 'id']
        });
    }
    
    // 安全地渲染用户输入
    renderUserContent(content) {
        return this.sanitizer.sanitize(content, {
            RETURN_DOM: true,
            RETURN_DOM_FRAGMENT: true
        });
    }
    
    // URL参数安全检查
    validateURL(url) {
        try {
            const parsedURL = new URL(url);
            return parsedURL.protocol === 'https:' || 
                   parsedURL.protocol === 'http:';
        } catch {
            return false;
        }
    }
}

CSRF防护机制 🔐

// 1. CSRF Token管理器
class CSRFTokenManager {
    constructor() {
        this.tokenName = 'csrf-token';
        this.token = this.generateToken();
    }
    
    generateToken() {
        return Array.from(
            crypto.getRandomValues(new Uint8Array(32)),
            byte => byte.toString(16).padStart(2, '0')
        ).join('');
    }
    
    // 为请求添加CSRF Token
    addTokenToRequest(request) {
        if (request instanceof Headers) {
            request.append(this.tokenName, this.token);
        } else if (request instanceof FormData) {
            request.append(this.tokenName, this.token);
        } else if (typeof request === 'object') {
            request[this.tokenName] = this.token;
        }
        return request;
    }
    
    // 验证CSRF Token
    validateToken(token) {
        return token === this.token;
    }
}

// 2. 安全请求包装器
class SecureRequestWrapper {
    constructor(csrfManager) {
        this.csrfManager = csrfManager;
    }
    
    async fetch(url, options = {}) {
        // 添加CSRF Token
        const headers = new Headers(options.headers);
        this.csrfManager.addTokenToRequest(headers);
        
        // 添加安全头部
        headers.append('X-Content-Type-Options', 'nosniff');
        headers.append('X-Frame-Options', 'DENY');
        
        const response = await fetch(url, {
            ...options,
            headers,
            credentials: 'same-origin'
        });
        
        return response;
    }
}

输入验证与清理 🧹

// 1. 输入验证器
class InputValidator {
    // 通用验证规则
    static rules = {
        email: /^[^\s@]+@[^\s@]+\.[^\s@]+$/,
        phone: /^\+?[\d\s-]{10,}$/,
        url: /^https?:\/\/[\w\-\.]+(:\d+)?\/?\S*$/,
        username: /^[\w\-]{3,16}$/,
        password: /^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{8,}$/
    };
    
    static validate(value, type) {
        if (!this.rules[type]) {
            throw new Error(`Unknown validation type: ${type}`);
        }
        return this.rules[type].test(value);
    }
    
    // SQL注入检测
    static checkSQLInjection(value) {
        const sqlPatterns = [
            /(\s|^)(SELECT|INSERT|UPDATE|DELETE|DROP|UNION|ALTER)(\s|$)/i,
            /'.*?'|\s+OR\s+'.*?'/i,
            /--|\#|\/\*/
        ];
        
        return !sqlPatterns.some(pattern => pattern.test(value));
    }
    
    // 命令注入检测
    static checkCommandInjection(value) {
        const cmdPatterns = [
            /[;&|`]/,
            /\$\([^)]*\)/,
            /\${[^}]*}/
        ];
        
        return !cmdPatterns.some(pattern => pattern.test(value));
    }
}

// 2. 输入清理器
class InputSanitizer {
    // HTML特殊字符转义
    static escapeHTML(input) {
        return input.replace(/[&<>"']/g, char => ({
            '&': '&amp;',
            '<': '&lt;',
            '>': '&gt;',
            '"': '&quot;',
            "'": '&#39;'
        })[char]);
    }
    
    // 移除危险字符
    static removeDangerousChars(input) {
        return input.replace(/[<>'"();]/g, '');
    }
    
    // 规范化输入
    static normalize(input) {
        return input
            .trim()
            .normalize('NFKC')
            .replace(/\s+/g, ' ');
    }
}

安全存储实践 🗄️

// 1. 安全存储管理器
class SecureStorageManager {
    constructor(storage = localStorage) {
        this.storage = storage;
        this.encryptionKey = this.getOrCreateKey();
    }
    
    // 获取或创建加密密钥
    getOrCreateKey() {
        let key = this.storage.getItem('encryption_key');
        if (!key) {
            key = crypto.getRandomValues(new Uint8Array(32));
            this.storage.setItem('encryption_key', key);
        }
        return key;
    }
    
    // 加密数据
    async encrypt(data) {
        const encoder = new TextEncoder();
        const dataBuffer = encoder.encode(JSON.stringify(data));
        
        const iv = crypto.getRandomValues(new Uint8Array(12));
        const key = await crypto.subtle.importKey(
            'raw',
            this.encryptionKey,
            'AES-GCM',
            false,
            ['encrypt']
        );
        
        const encryptedData = await crypto.subtle.encrypt(
            {
                name: 'AES-GCM',
                iv
            },
            key,
            dataBuffer
        );
        
        return {
            data: Array.from(new Uint8Array(encryptedData)),
            iv: Array.from(iv)
        };
    }
    
    // 解密数据
    async decrypt(encryptedData) {
        const key = await crypto.subtle.importKey(
            'raw',
            this.encryptionKey,
            'AES-GCM',
            false,
            ['decrypt']
        );
        
        const decryptedData = await crypto.subtle.decrypt(
            {
                name: 'AES-GCM',
                iv: new Uint8Array(encryptedData.iv)
            },
            key,
            new Uint8Array(encryptedData.data)
        );
        
        const decoder = new TextDecoder();
        return JSON.parse(decoder.decode(decryptedData));
    }
}

// 2. 敏感数据处理器
class SensitiveDataHandler {
    // 掩码处理
    static mask(value, start = 0, end) {
        const str = String(value);
        const maskLength = end ? end - start : str.length - start;
        const maskStr = '*'.repeat(maskLength);
        return str.slice(0, start) + maskStr + str.slice(start + maskLength);
    }
    
    // 数据脱敏
    static desensitize(data, rules) {
        const result = { ...data };
        
        for (const [key, rule] of Object.entries(rules)) {
            if (result[key]) {
                result[key] = this.mask(
                    result[key],
                    rule.start,
                    rule.end
                );
            }
        }
        
        return result;
    }
}

安全通信实践 📡

// 1. 安全WebSocket
class SecureWebSocket {
    constructor(url, options = {}) {
        this.url = url;
        this.options = options;
        this.reconnectAttempts = 0;
        this.maxReconnectAttempts = options.maxReconnectAttempts || 5;
        this.init();
    }
    
    init() {
        this.ws = new WebSocket(this.url);
        this.setupEventHandlers();
    }
    
    setupEventHandlers() {
        this.ws.onopen = () => {
            this.reconnectAttempts = 0;
            if (this.options.onOpen) {
                this.options.onOpen();
            }
        };
        
        this.ws.onclose = () => {
            if (this.reconnectAttempts < this.maxReconnectAttempts) {
                setTimeout(() => {
                    this.reconnectAttempts++;
                    this.init();
                }, 1000 * Math.pow(2, this.reconnectAttempts));
            }
        };
        
        this.ws.onmessage = async (event) => {
            try {
                const data = JSON.parse(event.data);
                if (this.options.onMessage) {
                    this.options.onMessage(data);
                }
            } catch (error) {
                console.error('Invalid message format:', error);
            }
        };
    }
    
    send(data) {
        if (this.ws.readyState === WebSocket.OPEN) {
            this.ws.send(JSON.stringify(data));
        }
    }
    
    close() {
        this.ws.close();
    }
}

// 2. 安全HTTP客户端
class SecureHTTPClient {
    constructor(baseURL) {
        this.baseURL = baseURL;
        this.interceptors = [];
    }
    
    // 添加请求拦截器
    addInterceptor(interceptor) {
        this.interceptors.push(interceptor);
    }
    
    // 应用拦截器
    async applyInterceptors(config) {
        let currentConfig = { ...config };
        
        for (const interceptor of this.interceptors) {
            currentConfig = await interceptor(currentConfig);
        }
        
        return currentConfig;
    }
    
    // 发送请求
    async request(config) {
        const finalConfig = await this.applyInterceptors({
            ...config,
            headers: {
                'Content-Type': 'application/json',
                ...config.headers
            }
        });
        
        try {
            const response = await fetch(
                this.baseURL + finalConfig.url,
                finalConfig
            );
            
            if (!response.ok) {
                throw new Error(`HTTP error! status: ${response.status}`);
            }
            
            return await response.json();
        } catch (error) {
            console.error('Request failed:', error);
            throw error;
        }
    }
}

最佳实践建议 💡

  1. 安全检查工具
// 1. 安全检查器
class SecurityChecker {
    // 检查安全头部
    static checkSecurityHeaders(response) {
        const requiredHeaders = {
            'Content-Security-Policy': true,
            'X-Content-Type-Options': 'nosniff',
            'X-Frame-Options': ['DENY', 'SAMEORIGIN'],
            'X-XSS-Protection': '1; mode=block',
            'Strict-Transport-Security': true
        };
        
        const issues = [];
        
        for (const [header, value] of Object.entries(requiredHeaders)) {
            const actualValue = response.headers.get(header);
            
            if (!actualValue) {
                issues.push(`Missing ${header}`);
            } else if (value !== true) {
                if (Array.isArray(value)) {
                    if (!value.includes(actualValue)) {
                        issues.push(
                            `Invalid ${header}: ${actualValue}`
                        );
                    }
                } else if (value !== actualValue) {
                    issues.push(
                        `Invalid ${header}: ${actualValue}`
                    );
                }
            }
        }
        
        return issues;
    }
    
    // 检查安全配置
    static checkSecurityConfig() {
        const issues = [];
        
        // 检查HTTPS
        if (window.location.protocol !== 'https:') {
            issues.push('Not using HTTPS');
        }
        
        // 检查Cookies配置
        document.cookie.split(';').forEach(cookie => {
            if (!cookie.includes('Secure')) {
                issues.push('Cookie without Secure flag');
            }
            if (!cookie.includes('HttpOnly')) {
                issues.push('Cookie without HttpOnly flag');
            }
            if (!cookie.includes('SameSite')) {
                issues.push('Cookie without SameSite attribute');
            }
        });
        
        return issues;
    }
}

// 2. 安全审计工具
class SecurityAuditor {
    constructor() {
        this.vulnerabilities = [];
    }
    
    // 检查DOM XSS漏洞
    checkDOMXSS() {
        const dangerousProps = [
            'innerHTML',
            'outerHTML',
            'insertAdjacentHTML',
            'document.write'
        ];
        
        const scripts = document.getElementsByTagName('script');
        for (const script of scripts) {
            const content = script.textContent;
            dangerousProps.forEach(prop => {
                if (content.includes(prop)) {
                    this.vulnerabilities.push({
                        type: 'DOM XSS',
                        location: script.src || 'inline script',
                        description: `Using dangerous property: ${prop}`
                    });
                }
            });
        }
    }
    
    // 检查不安全的配置
    checkInsecureConfigs() {
        // 检查eval使用
        if (window.eval) {
            this.vulnerabilities.push({
                type: 'Insecure Config',
                description: 'eval is enabled'
            });
        }
        
        // 检查内联事件处理器
        document.querySelectorAll('*').forEach(element => {
            for (const attr of element.attributes) {
                if (attr.name.startsWith('on')) {
                    this.vulnerabilities.push({
                        type: 'Insecure Config',
                        description: `Inline event handler: ${attr.name}`,
                        element: element.tagName
                    });
                }
            }
        });
    }
    
    // 生成审计报告
    generateReport() {
        return {
            timestamp: new Date().toISOString(),
            vulnerabilities: this.vulnerabilities,
            summary: {
                total: this.vulnerabilities.length,
                byType: this.vulnerabilities.reduce((acc, vuln) => {
                    acc[vuln.type] = (acc[vuln.type] || 0) + 1;
                    return acc;
                }, {})
            }
        };
    }
}

结语 📝

JavaScript安全编程是一个复杂且重要的话题,需要我们在开发过程中始终保持警惕。我们学习了:

  1. XSS防护技术
  2. CSRF防御机制
  3. 输入验证与清理
  4. 安全存储实践
  5. 安全通信策略

💡 学习建议:安全性应该在开发的每个阶段都被考虑,而不是作为事后的补充。建议经常进行安全审计,及时修复发现的漏洞。


如果你觉得这篇文章有帮助,欢迎点赞收藏,也期待在评论区看到你的想法和建议!👇

终身学习,共同成长。

咱们下一期见

💻

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2277042.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【算法学习】——整数划分问题详解(动态规划)

&#x1f9ee;整数划分问题是一个较为常见的算法题&#xff0c;很多问题从整数划分这里出发&#xff0c;进行包装&#xff0c;形成新的题目&#xff0c;所以完全理解整数划分的解决思路对于之后的进一步学习算法是很有帮助的。 「整数划分」通常使用「动态规划」解决&#xff0…

文件与IO流:一

一些常识 硬盘特点 擅长顺序读&#xff0c;不擅长随机读&#xff0c;尤其是机械硬盘。 随机读例如某个目录中的所有小文件的复制&#xff0c;顺序读是某个大文件的整体复制。 windows的文件系统是按照“树形结构”来组织文件。 路径的风格 1.绝对路径&#xff1a;从根节点…

计算机网络 (42)远程终端协议TELNET

前言 Telnet&#xff08;Telecommunication Network Protocol&#xff09;是一种网络协议&#xff0c;属于TCP/IP协议族&#xff0c;主要用于提供远程登录服务。 一、概述 Telnet协议是一种远程终端协议&#xff0c;它允许用户通过终端仿真器连接到远程主机&#xff0c;并在远程…

WPF系列十二:图形控件CombinedGeometry

简介 CombinedGeometry 是 WPF (Windows Presentation Foundation) 中的一个几何对象&#xff0c;用于将两个几何图形组合成一个新的几何图形。它允许你通过不同的组合模式&#xff08;如相交、并集、差集或异或&#xff09;来创建复杂的形状。常与 Path 控件一起使用来绘制组…

《计算机网络》课后探研题书面报告_网际校验和算法

网际校验和算法 摘 要 本文旨在研究和实现网际校验和&#xff08;Internet Checksum&#xff09;算法。通过阅读《RFC 1071》文档理解该算法的工作原理&#xff0c;并使用编程语言实现网际校验和的计算过程。本项目将对不同类型的网络报文&#xff08;包括ICMP、TCP、UDP等&a…

业务幂等性技术架构体系之接口幂等深入剖析

在实际应用中&#xff0c;由于网络不稳定、系统延迟等原因&#xff0c;客户端可能会重复发送相同的请求。如果这些重复请求都被服务器处理并执行&#xff0c;就可能导致意想不到的问题&#xff0c;比如重复扣款、多次下单或者数据不一致等。 这就是为什么我们需要接口幂等性。…

sql模糊关联匹配

需求目标&#xff1a; 建立临时表 drop table grafana_bi.zbj_gift_2024;USE grafana_bi; CREATE TABLE zbj_gift_2024 (id INT AUTO_INCREMENT PRIMARY KEY,userName VARCHAR(255),giftName VARCHAR(255),giftNum INT,points INT,teacher VARCHAR(255),sendDate DATETIME,…

《蜜蜂路线》

题目背景 无 题目描述 一只蜜蜂在下图所示的数字蜂房上爬动,已知它只能从标号小的蜂房爬到标号大的相邻蜂房,现在问你&#xff1a;蜜蜂从蜂房 mm 开始爬到蜂房 nn&#xff0c;m<nm<n&#xff0c;有多少种爬行路线&#xff1f;&#xff08;备注&#xff1a;题面有误&am…

LeetCode100之搜索二维矩阵(46)--Java

1.问题描述 给你一个满足下述两条属性的 m x n 整数矩阵&#xff1a; 每行中的整数从左到右按非严格递增顺序排列。每行的第一个整数大于前一行的最后一个整数。 给你一个整数 target &#xff0c;如果 target 在矩阵中&#xff0c;返回 true &#xff1b;否则&#xff0c;返回…

JS爬虫实战演练

在这个小红书私信通里面进行一个js的爬虫 文字发送 async function sendChatMessage(content) {const url https://pro.xiaohongshu.com/api/edith/ads/pro/chat/chatline/msg;const params new URLSearchParams({porch_user_id: 677e116404ee000000000001});const messageD…

自动连接校园网wifi脚本实践(自动网页认证)

目录 起因执行步骤分析校园网登录逻辑如何判断当前是否处于未登录状态&#xff1f; 书写代码打包设置开机自动启动 起因 我们一般通过远程控制的方式访问实验室电脑&#xff0c;但是最近实验室老是断电&#xff0c;但重启后也不会自动连接校园网账户认证&#xff0c;远程工具&…

WPS计算机二级•表格函数计算

听说这里是目录哦 函数基础知识 相对绝对混合引用&#x1f32a;️相对引用绝对引用混合引用 常用求和函数 SUM函数&#x1f326;️语法说明 函数快速求 平均数最值⚡平均数最值 实用统计函数 实现高效统计&#x1f300;COUNTCOUNTIF 实用文本函数 高效整理数据&#x1f308;RIG…

自动化测试工具Ranorex Studio(八十九)-解决方案浏览器

解决方案浏览器 除了为项目添加条目外&#xff0c;’Solution Explorer’允许你编辑解决方案的其他辅助选项。 例如&#xff0c;增加文件夹从而将项目中的录制模块和代码模块分离开来。 图&#xff1a;在solution browser中为项目添加文件夹 另外&#xff0c;你可以删除不用的…

2025 年 UI 大屏设计新风向

在科技日新月异的 2025 年&#xff0c;UI 大屏设计领域正经历着深刻的变革。随着技术的不断进步和用户需求的日益多样化&#xff0c;新的设计风向逐渐显现。了解并掌握这些趋势&#xff0c;对于设计师打造出更具吸引力和实用性的 UI 大屏作品至关重要。 一、沉浸式体验设计 如…

绘制三角形、正六边形、五角星、六角星

<!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>绘制图形</title><style>body {displ…

LLM实现视频切片合成 前沿知识调研

1.相关产品 产品链接腾讯智影https://zenvideo.qq.com/可灵https://klingai.kuaishou.com/即梦https://jimeng.jianying.com/ai-tool/home/Runwayhttps://aitools.dedao.cn/ai/runwayml-com/Descripthttps://www.descript.com/?utm_sourceai-bot.cn/Opus Cliphttps://www.opu…

Node.js - HTTP

1. HTTP请求 HTTP&#xff08;Hypertext Transfer Protocol&#xff0c;超文本传输协议&#xff09;是客户端和服务器之间通信的基础协议。HTTP 请求是由客户端&#xff08;通常是浏览器、手机应用或其他网络工具&#xff09;发送给服务器的消息&#xff0c;用来请求资源或执行…

鸿蒙中自定义slider实现字体大小变化

ui&#xff1a; import { display, mediaquery, router } from kit.ArkUI import CommonConstants from ./CommonConstants; import PreferencesUtil from ./PreferencesUtil; import StyleConstants from ./StyleConstants;// 字体大小 Entry Component struct FontSize {Sta…

Springboot + vue 小区物业管理系统

&#x1f942;(❁◡❁)您的点赞&#x1f44d;➕评论&#x1f4dd;➕收藏⭐是作者创作的最大动力&#x1f91e; &#x1f496;&#x1f4d5;&#x1f389;&#x1f525; 支持我&#xff1a;点赞&#x1f44d;收藏⭐️留言&#x1f4dd;欢迎留言讨论 &#x1f525;&#x1f525;&…

uni-app编写微信小程序使用uni-popup搭配uni-popup-dialog组件在ios自动弹出键盘。

uni-popup-dialog 对话框 将 uni-popup 的type属性改为 dialog&#xff0c;并引入对应组件即可使用对话框 &#xff0c;该组件不支持单独使用 示例 <button click"open">打开弹窗</button> <uni-popup ref"popup" type"dialog"…