Replies: 1 comment
|
Hi, we hit exactly the same issue: Chrome/Chromium strips the port from the Origin header for loopback URLs ( We filed a bug report with the root cause and a suggested fix (compare hostname only, ignore the port): We also maintain a green "double-click to run" launcher distribution that already fixes this with an idempotent patch (Origin check changed to hostname comparison; in LAN mode it also merges the machine's LAN IPs into trustedHosts). Feel free to reference the approach or use it directly:
你好,我们遇到了完全一样的问题:Chrome/Chromium 对回环地址( 同时我们维护的绿色整合版启动器已经解决该问题(自动打幂等补丁:Origin 校验改 hostname 比较,局域网模式自动并入本机局域网 IP),欢迎参考方案或直接使用:
本回复由 AI 辅助撰写 / This reply was drafted with AI assistance. |
Uh oh!
There was an error while loading. Please reload this page.
Web GUI: every /api call returns 403 when opened via http://127.0.0.1:3080 (works via localhost)
环境 / Environment
0.1.0-rc.6(global npm install, web profile)dsh web(default 127.0.0.1:3080), fresh install/start现象 / Symptom
Open the Web GUI at
http://127.0.0.1:3080/in Chrome: the page loads, but every/api/*RPC fails with HTTP 403, e.g. the GUI showstransport failure for /api/llm.providers: HTTP 403(alsohost.describe,settings.describe, …). The same GUI opened athttp://localhost:3080/works fine (all requests return 200).请求头抓包 / Captured request (DevTools, failing request)
The
Sec-Fetch-Site: same-origin+Refererprove the request is genuinely same-origin; only theOriginserialization differs.根因 / Root cause
packages/client/connection(built:lib/index.js, source likelysrc/types/api-request-trust.ts),isTrustedApiRequest()ends with a strict host:port equality between theOriginheader and theHostheader:Recent Chrome versions serialize the
Originheader without the port when the initiator origin's host is an IP literal such as127.0.0.1(known behavior change; e.g. https://stackoverflow.com/questions/79625700/chrome-sending-wrong-origin-header-on-127-0-0-1, and other projects had to adapt, e.g. onyx-dot-app/onyx#9382 "ignore port when determining origin in dev").localhostis not affected (the port is still serialized), which explains the asymmetry.Verified server-side against a live
dsh webinstance with the exact captured headers:http://127.0.0.1(no port)127.0.0.1:3080http://127.0.0.1:3080127.0.0.1:3080http://localhost:3080localhost:3080Impact: every
/api/*route (HTTP bridge + the shared-channel interceptor + the WebSocket downlink gate all call the sameisTrustedApiRequest), so the whole GUI is broken on127.0.0.1for affected Chrome versions.建议修复 / Suggested fix
Tolerate a port-less
Originheader while keeping the protection: require the hostname to match, and only require the port to match when theOriginheader actually carries one (the request's authority/port remains enforced via the already-validatedHostheader):This keeps the DNS-rebinding / cross-site defense (non-loopback or untrusted Host is still rejected earlier; a mismatched hostname or an explicit mismatched port is still rejected) while no longer false-positiving on Chrome's port-less
Originserialization.备注 / Note
Requestwith a fake authority (http://dsh.internal), so the fix should keep comparing against theHostheader (the wire authority) rather thanrequest.url.http://localhost:3080instead ofhttp://127.0.0.1:3080(identical server/session).All reactions