// 安全性测试
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',
'contextMenus'
]
const actualPermissions = [
'storage',
'activeTab',
'contextMenus'
]
// 验证权限列表匹配
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(/