背景与价值开放重定向可被滥用进行钓鱼与令牌盗用。通过白名单与带过期签名的短链治理,可大幅降低攻击面并实现可追踪。统一规范允许域白名单:只允许业务批准的 `https` 域名与路径前缀。短链签名:对目标路径与过期时间进行HMAC签名,拒绝过期或签名不匹配。同源限制:默认仅允许同源或白名单外跳;开发例外需单列域名。核心实现白名单与同源校验const allowOrigins = new Set([
'https://app.example.com',
'https://www.example.com',
'https://docs.example.com'
])
function allowedRedirect(url: string): boolean {
try {
const u = new URL(url)
if (u.protocol !== 'https:') return false
const origin = u.origin
if (allowOrigins.has(origin)) return true
return false
} catch {
return false
}
}
短链签名与过期function enc(s: string): Uint8Array { return new TextEncoder().encode(s) }
async function hmacSha256(key: CryptoKey, data: string): Promise<string> {
const raw = await crypto.subtle.sign('HMAC', key, enc(data))
const u = new Uint8Array(raw)
let s = ''
for (let i = 0; i < u.length; i++) s += String.fromCharCode(u[i])
return btoa(s).replace(/\+/g,'-').replace(/\//g,'_').replace(/=+$/,'')
}
async function importHmacKey(secret: ArrayBuffer): Promise<CryptoKey> {
return crypto.subtle.importKey('raw', secret, { name: 'HMAC', hash: 'SHA-256' }, false, ['sign'])
}
type Token = { target: string; exp: number; sig: string }
async function signToken(target: string, exp: number, key: CryptoKey): Promise<Token> {
const payload = target + '|' + String(exp)
const sig = await hmacSha256(key, payload)
return { target, exp, sig }
}
async function verifyToken(t: Token, key: CryptoKey): Promise<boolean> {
if (typeof t.exp !== 'number' || Date.now() > t.exp) return false
if (!allowedRedirect(t.target)) return false
const payload = t.target + '|' + String(t.exp)
const s = await hmacSha256(key, payload)
return s === t.sig
}
落地建议仅允许白名单域与路径前缀外跳,默认拒绝非 `https` 与非白名单目标。短链必须包含过期时间并使用HMAC签名,过期或签名不匹配立即拒绝。审计记录外跳请求与目标域,便于发现异常行为并快速处置。验证清单目标URL是否命中白名单且为 `https`。短链是否包含过期时间并通过HMAC签名校验。外跳审计是否记录来源、目标与时间戳。

发表评论 取消回复