核心要点外部 `script`/`link` 必须携带 `integrity` 与 `crossorigin`;哈希使用 `sha256`。校验失败时触发回退到受信来源;记录审计信息。实现示例function parseSri(integrity: string): { alg: 'sha256'; b64: string } | null {
const m = /^sha256-([A-Za-z0-9+/=]+)$/.exec(integrity)
return m ? { alg: 'sha256', b64: m[1] } : null
}
async function sha256Base64(buf: Uint8Array): Promise<string> {
const d = await crypto.subtle.digest('SHA-256', buf)
return Buffer.from(d).toString('base64')
}
async function fetchBytes(url: string): Promise<Uint8Array> {
const r = await fetch(url, { cache: 'no-store' })
const b = await r.arrayBuffer()
return new Uint8Array(b)
}
async function verify(url: string, integrity: string): Promise<boolean> {
const sri = parseSri(integrity)
if (!sri) return false
const buf = await fetchBytes(url)
const calc = await sha256Base64(buf)
return calc === sri.b64
}
function setAttributes(el: HTMLScriptElement | HTMLLinkElement, integrity: string, crossorigin: 'anonymous' | 'use-credentials' = 'anonymous') {
el.setAttribute('integrity', integrity)
el.setAttribute('crossorigin', crossorigin)
}
async function loadWithFallback(el: HTMLScriptElement | HTMLLinkElement, primary: { url: string; integrity: string }, fallback?: { url: string; integrity: string }): Promise<boolean> {
if (await verify(primary.url, primary.integrity)) {
setAttributes(el, primary.integrity)
el.setAttribute(el instanceof HTMLScriptElement ? 'src' : 'href', primary.url)
return true
}
if (fallback && await verify(fallback.url, fallback.integrity)) {
setAttributes(el, fallback.integrity)
el.setAttribute(el instanceof HTMLScriptElement ? 'src' : 'href', fallback.url)
return true
}
return false
}
审计与运行治理审计记录包含主/回退来源与哈希;失败时阻断并告警。外部资源域名进入白名单治理;版本与哈希需与发布一致。

发表评论 取消回复