一、CSP与Report-To基线Content-Security-Policy: default-src 'none'; script-src 'self' 'strict-dynamic'; connect-src 'self'; img-src 'self'; style-src 'self'; frame-ancestors 'none'; report-to csp-endpoint Report-To: {"group":"csp-endpoint","max_age":10800,"endpoints":[{"url":"https://report.example.com/csp"}]} 二、报告模型与聚合type CspReport = { documentURL: string; effectiveDirective: string; blockedURI: string; sourceFile?: string; lineNumber?: number; disposition?: string } class Aggregator { counts = new Map<string, number>() inc(key: string) { const n = (this.counts.get(key) || 0) + 1; this.counts.set(key, n) } top(threshold: number): string[] { return Array.from(this.counts.entries()).filter(([_, n]) => n >= threshold).map(([k]) => k) } } function keyOf(rep: CspReport): string { const blocked = rep.blockedURI || 'unknown' const dir = rep.effectiveDirective || 'unknown' try { const u = new URL(blocked); return `${dir}:${u.origin}` } catch { return `${dir}:${blocked}` } } 三、速率限制与审计class RateGate { windowMs: number max: number hits = new Map<string, number[]>() constructor(windowMs: number, max: number) { this.windowMs = windowMs; this.max = max } allow(key: string): boolean { const now = Date.now() const arr = (this.hits.get(key) || []).filter(t => now - t < this.windowMs) if (arr.length >= this.max) return false arr.push(now); this.hits.set(key, arr); return true } } type Audit = { id: string; key: string; count: number; timestamp: string } function recordAudit(key: string, count: number): Audit { return { id: String(Date.now()), key, count, timestamp: new Date().toISOString() } } 四、处置策略生成与灰度type PolicyUpdate = { allow?: string[]; deny?: string[] } function generateUpdate(keys: string[]): PolicyUpdate { const allow: string[] = [] const deny: string[] = [] for (const k of keys) { const [dir, origin] = k.split(':') if (dir === 'img-src' || dir === 'style-src') allow.push(origin) else deny.push(origin) } return { allow, deny } } function applyCspStage(res: { setHeader: (k: string, v: string) => void }, stage: 'baseline' | 'gray') { const base = "default-src 'none'; script-src 'self' 'strict-dynamic'; connect-src 'self'; img-src 'self'; style-src 'self'; frame-ancestors 'none'" const gray = base + '; report-to csp-endpoint' res.setHeader('Content-Security-Policy', stage === 'baseline' ? base : gray) } 五、工作流整合function handleReports(items: CspReport[], agg: Aggregator, gate: RateGate, threshold: number): { update?: PolicyUpdate; audit?: Audit[] } { const audits: Audit[] = [] for (const i of items) { const key = keyOf(i) if (!gate.allow(key)) continue agg.inc(key) } const keys = agg.top(threshold) for (const k of keys) audits.push(recordAudit(k, agg.counts.get(k) || 0)) const update = keys.length ? generateUpdate(keys) : undefined return { update, audit: audits } } 六、验收清单报告聚合按`effectiveDirective+origin`统计;阈值触发处置;速率限制有效防止噪声。处置策略分离`allow/deny`并灰度发布;CSP头语法与值校验正确。审计记录包含处置Key与计数、时间戳;可回滚与复盘。

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论
立即
投稿

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部
1.978790s