/** * Unit Tests for Security Fixes * * 这些是不需要运行服务器的纯单元测试 * 可以直接运行: npm test -- tests/security-fixes.unit.test.js */ import { describe, test, expect } from '@jest/globals'; // ========== 模拟 sanitizeProviderData 函数 ========== function sanitizeProviderData(provider) { if (!provider || typeof provider !== 'object') return provider; const sanitized = { ...provider }; if (typeof sanitized.customName === 'string') { let name = sanitized.customName; // 拒绝包含危险协议 if (/(?:data|javascript|vbscript)\s*:/i.test(name)) { sanitized.customName = ''; return sanitized; } // 移除所有 HTML 标签 name = name.replace(/<[^>]*>/g, ''); // 移除 HTML 事件处理器属性 name = name.replace(/\s+on\w+\s*=\s*(?:"[^"]*"|'[^']*'|[^\s>]*)/gi, ''); // 移除潜在的 HTML 实体编码攻击 name = name.replace(/&[#\w]+;/g, ''); sanitized.customName = name.trim(); } return sanitized; } // ========== 模拟 withTimeout 函数 ========== function withTimeout(promise, ms = 30000) { return Promise.race([ promise, new Promise((_, reject) => setTimeout(() => reject(new Error(`Operation timeout after ${ms}ms`)), ms) ) ]); } // ========== 模拟路径验证逻辑 ========== import path from 'path'; function validatePath(inputPath, cwd) { const resolved = path.resolve(cwd, inputPath); const relativePath = path.relative(cwd, resolved); const isInsideCwd = !path.isAbsolute(relativePath) && !relativePath.startsWith('..') && relativePath !== '..'; const isWindows = process.platform === 'win32'; const normalizedResolved = (isWindows ? resolved.toLowerCase() : resolved).replace(/\\/g, '/'); const normalizedCwd = (isWindows ? cwd.toLowerCase() : cwd).replace(/\\/g, '/'); const startsWithCwd = normalizedResolved.startsWith(normalizedCwd + '/') || normalizedResolved === normalizedCwd; return isInsideCwd && startsWithCwd; } describe('Unit Tests - sanitizeProviderData', () => { test('should remove script tags', () => { const input = { customName: 'TestProvider' }; const result = sanitizeProviderData(input); expect(result.customName).not.toContain(''); expect(result.customName).toContain('TestProvider'); }); test('should reject javascript: protocol', () => { const input = { customName: 'javascript:alert("XSS")' }; const result = sanitizeProviderData(input); expect(result.customName).toBe(''); }); test('should reject data: protocol', () => { const input = { customName: 'data:text/html,' }; const result = sanitizeProviderData(input); expect(result.customName).toBe(''); }); test('should reject vbscript: protocol', () => { const input = { customName: 'vbscript:msgbox("XSS")' }; const result = sanitizeProviderData(input); expect(result.customName).toBe(''); }); test('should remove all HTML tags', () => { const input = { customName: '