fix(trust-fence): Origin 校验改按 hostname 比较,对齐 DSH 网关栅栏(Edge 151 无端口 Origin 修复)
镜像栅栏此前按 host(含端口)比较 Origin,而部分 Chromium 构建(Edge 151)会把非默认端口 loopback 页面的 Origin 序列化为不带端口的形式,导致 /sidebar/* 在 Edge 151 下全部 403 forbidden。DSH 官方栅栏(api-request-trust.ts)已改为 hostname 比较,本提交同步该语义:端口不再重决信任,Host 栅栏与 sec-fetch-site 拒绝逻辑不变。 测试:tests/trusted-hosts.spec.ts 新增无端口 Origin 放行、不同 hostname 拒绝、null origin 拒绝三个回归用例;本地 scratch 挂载 + curl 实测通过。
This commit is contained in:
+8
-1
@@ -67,10 +67,17 @@ export function isTrustedApiRequest(request: ApiTrustRequest, trustedHosts: read
|
||||
if (hostUrl === undefined) return false
|
||||
if (!isLoopbackHostname(hostUrl.hostname) && !isTrustedAuthority(hostUrl, trustedHosts)) return false
|
||||
if (header(request.headers, 'sec-fetch-site') === 'cross-site') return false
|
||||
// Origin fence: when a browser attaches an Origin it must name this
|
||||
// hostname (the Host fence above already bound the authority, so the port
|
||||
// must not re-decide trust). Comparing hostname, not host: some Chromium
|
||||
// builds (Edge 151) serialize the Origin of a non-default-port loopback page
|
||||
// without the port, and refusing those bricks every /sidebar route. Absent
|
||||
// Origin is fine — the Host fence above already bound the request. The
|
||||
// literal "null" (sandboxed iframes, file: pages) is an opaque origin, refused.
|
||||
const origin = header(request.headers, 'origin')
|
||||
if (origin === undefined) return true
|
||||
try {
|
||||
return new URL(origin).host === hostUrl.host
|
||||
return new URL(origin).hostname === hostUrl.hostname
|
||||
} catch {
|
||||
return false
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user