// 安全性测试 describe('安全性测试', () => { describe('输入验证和XSS防护', () => { it('应该过滤危险的HTML标签', async () => { const { BaiduAdapter } = await import('../../src/services/adapters/baidu') const adapter = new BaiduAdapter() const dangerousInputs = [ '', '', 'javascript:alert("XSS")', '', '">', '\';alert("XSS");//' ] for (const dangerousInput of dangerousInputs) { const params = { keyword: dangerousInput, engine: 'baidu' as const } const url = adapter.buildQuery(params) // 验证危险字符被正确编码 expect(url).not.toContain('', 'vbscript:msgbox("XSS")', '../../etc/passwd', 'file:///etc/passwd' ] for (const maliciousUrl of maliciousUrls) { const params = { keyword: '测试', engine: 'baidu' as const, site: maliciousUrl } const result = adapter.validateParams(params) // 验证恶意URL被拒绝 if (maliciousUrl.startsWith('javascript:') || maliciousUrl.startsWith('data:') || maliciousUrl.startsWith('vbscript:')) { expect(result.isValid).toBe(false) expect(result.errors.length).toBeGreaterThan(0) } } }) it('应该限制输入长度', async () => { const { BaiduAdapter } = await import('../../src/services/adapters/baidu') const adapter = new BaiduAdapter() // 超长输入测试 const longKeyword = 'a'.repeat(10000) const params = { keyword: longKeyword, engine: 'baidu' as const } const result = adapter.validateParams(params) // 应该对超长输入给出警告 expect(result.warnings.length).toBeGreaterThan(0) expect(result.warnings.some(w => w.includes('过长'))).toBe(true) }) }) describe('数据存储安全', () => { it('应该加密敏感数据', async () => { // 模拟加密存储 const encryptData = (data: any): string => { return Buffer.from(JSON.stringify(data)).toString('base64') } const decryptData = (encryptedData: string): any => { return JSON.parse(Buffer.from(encryptedData, 'base64').toString()) } const sensitiveData = { userSettings: { defaultEngine: 'baidu', enableHistory: true, // 其他敏感设置 }, searchHistory: [ { keyword: '机密搜索', timestamp: Date.now() } ] } const encrypted = encryptData(sensitiveData) const decrypted = decryptData(encrypted) expect(encrypted).not.toBe(JSON.stringify(sensitiveData)) expect(decrypted).toEqual(sensitiveData) }) it('应该限制存储数据量', async () => { const maxStorageSize = 5 * 1024 * 1024 // 5MB限制 const currentSize = 0 // 模拟存储大小检查 const checkStorageLimit = (newData: any): boolean => { const dataSize = new Blob([JSON.stringify(newData)]).size return currentSize + dataSize < maxStorageSize } const largeData = { history: Array.from({ length: 100000 }, (_, i) => ({ id: `item-${i}`, data: 'x'.repeat(1000) // 每项1KB })) } const canStore = checkStorageLimit(largeData) expect(canStore).toBe(false) }) it('应该定期清理过期数据', async () => { const now = Date.now() const expirationTime = 30 * 24 * 60 * 60 * 1000 // 30天 const oldData = { id: 'old-item', timestamp: now - (expirationTime + 86400000), // 超过30天 data: '过期数据' } const newData = { id: 'new-item', timestamp: now, data: '新数据' } const isExpired = (item: any): boolean => { return now - item.timestamp > expirationTime } expect(isExpired(oldData)).toBe(true) expect(isExpired(newData)).toBe(false) // 模拟数据清理 const cleanExpiredData = (data: any[]): any[] => { return data.filter(item => !isExpired(item)) } const cleanedData = cleanExpiredData([oldData, newData]) expect(cleanedData).toHaveLength(1) expect(cleanedData[0].id).toBe('new-item') }) }) describe('权限控制', () => { it('应该只申请必要的权限', () => { // 检查manifest.json中的权限 const requiredPermissions = [ 'storage', 'activeTab', 'scripting' ] const actualPermissions = [ 'storage', 'activeTab', 'scripting' ] // 验证权限列表匹配 expect(actualPermissions).toEqual(expect.arrayContaining(requiredPermissions)) expect(actualPermissions.length).toBeLessThanOrEqual(requiredPermissions.length) }) it('应该验证主机权限', () => { const allowedHosts = [ '' ] // 验证主机权限的合理性 expect(allowedHosts).toContain('') // 如果有特定域名限制,应该在这里验证 const restrictedHosts = [ 'https://*.baidu.com/*', 'https://*.google.com/*', 'https://*.bing.com/*' ] // 在生产环境中,可能需要限制到特定搜索引擎 expect(restrictedHosts.every(host => host.startsWith('https://') && host.endsWith('/*') )).toBe(true) }) }) describe('内容安全策略', () => { it('应该实施CSP头部', () => { const cspHeader = { "default-src": "'self'", "script-src": "'self' 'unsafe-inline'", "style-src": "'self' 'unsafe-inline'", "img-src": "'self' data: https:", "connect-src": "'self' https://*.baidu.com https://*.google.com https://*.bing.com" } // 验证CSP配置 expect(cspHeader["default-src"]).toBe("'self'") expect(cspHeader["script-src"]).toContain("'self'") expect(cspHeader["connect-src"]).toContain("https://*.baidu.com") }) it('应该防止内联脚本执行', () => { const maliciousHTML = `
点击我
恶意链接 ` // 验证HTML清理 const sanitizeHTML = (html: string): string => { return html .replace(/on\w+="[^"]*"/g, '') // 移除事件处理器 .replace(/javascript:/g, '') // 移除javascript:协议 .replace(/]*>.*?<\/script>/gs, '') // 移除script标签 } const sanitized = sanitizeHTML(maliciousHTML) expect(sanitized).not.toContain('onclick=') expect(sanitized).not.toContain('javascript:') expect(sanitized).not.toContain('