Repository navigation
fix(upstream #110): 回环免 token 例外钉到扩展的稳定 Origin(安全修复) - #12
Merged
Merged
Conversation
…le origin Any installed extension could bypass bearer-token auth by presenting its own chrome-extension:// Origin (prefix check). The exemption is now an exact-match allowlist: the shipped extension pins a manifest key so its Chromium id (ampcoeplakeelcoengijbfbhjnlbdign) is stable across machines and updates, and that single origin is trusted by default. Every other origin must present the token; origin trust never applies off loopback. Hardening from adversarial review: - trustedExtensionOrigins entries are validated (chrome-extension://<a-p 32> only) and the effective allowlist is logged at mount; [] is the explicit hardened mode. A web-origin entry would have re-granted the trust this change removes. - Docs state the real boundary: the manifest key is public, so the pin stops incidental cross-extension access, not deliberate key-cloning; hardened deployments pair the token. Loopback-terminating proxies (tailscale serve, ssh -L) documented. - Updating from pre-0.1.5 changes the extension id once (settings are per id): READMEs and both installers now say to re-enter a configured remote bridge address/token. Extension version bumped to 0.1.5. - Drift guard: a test fails if the manifest key ever hashes to anything but the pinned id; malformed keys are rejected, not munged. - e2e now proves the pin: real Chromium must derive the pinned id and accept a tokenless hello against the default allowlist (plus the paired-token path), with a locale-independent harness and loud skips.
…e extension's stable origin Upstream-PR: omdsh-dev#110 Source: origin/pr/110 @ a118d3a Author: Toto Leung <to.watery8t@icloud.com> Conflicts(全部按 fork 现状解决): - manifest.json / manifest.firefox.json / extensions/dsh-browser/package.json:保留 fork 的 0.1.6,只接受 manifest.json 的 stable `key`(版本 bump 不进 fork) - packages/browser/bridge-browser/README*:保留 fork 的 engines 段落与信标/CORS 安全条目,并入 trustedExtensionOrigins 配置行与安全模型条目 - src/index.ts:fork 的信标/实例元信息与 PR 的 trustedExtensionOrigins 配置两侧都保留 - tests/index.spec.ts:beacon 与 trustedExtensionOrigins 的断言合并共存
上游按自身版本线写了「从 0.1.5 之前的版本升级」,与本 fork 的版本号(当前 0.1.6,且已发过 0.1.5)对不上。改为「从旧构建升级」,中英与两个安装脚本保持一致,行为不变。
This was referenced Oct 19, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
原始 PR / Upstream PR
origin/pr/110 @ a118d3amerge --no-ff(保留原提交与作者)key);升级提示改为不写具体版本号概述 / Summary
修复本地权限提升:回环免 token 的例外不再按
chrome-extension://前缀放行,而是精确匹配本扩展由 manifestkey派生的稳定 Origin。动机 / Motivation
桥原来对回环连接使用
origin.startsWith('chrome-extension://')判断是否免 token。于是任何已安装的扩展都能用自己的 Origin 免 token 连上本机 dsh 的桥,调用全套browser_*工具——这是一个本地权限提升面。要让「按扩展身份信任」成立,扩展 id 必须先稳定:加固定key后 Chromium 从它派生 id(ampcoeplakeelcoengijbfbhjnlbdign),跨机器、跨重装一致。改动内容 / Changes
extensions/dsh-browser/manifest.json增加 stablekey(公开 SPKI),扩展 id 从此固定。src/extension-origins.ts:固定 id 常量 + 由 key 派生的辅助函数(非法 DER 显式失败,不"凑"一个看似合理的 id)。Config.trustedExtensionOrigins:默认只含随附扩展 Origin;条目必须是精确的chrome-extension://<32 位 a–p>,[]为加固模式(全部强制 token),非法条目启动即失败;挂载时把生效白名单写入日志。server.ts:免 token 判定改为loopback && 白名单精确匹配。tailscale serve、ssh -L、nginx)需用加固模式。manifest.firefox.json、extensions/dsh-browser/package.json、manifest.json的版本号保留 fork 的 0.1.6(版本 bump 不进 fork);install.sh/install.ps1与根 README 的「从 0.1.5 之前的版本升级」改为「从旧构建升级」,与本 fork 的版本线对齐;桥 README 冲突保留 fork 的 engines 段落与信标/CORS 安全条目,并并入trustedExtensionOrigins配置行。测试 / Testing
pnpm run typecheck/pnpm run check:runtime/pnpm run build通过。pnpm run test:桥插件 220 用例、扩展 586 用例全过。其中tests/extension-origins.spec.ts新增漂移守卫(manifest key 必须哈希出固定 id,畸形 key 被拒绝);tests/index.spec.ts/tests/server.spec.ts覆盖默认值、非法条目、空名单、未列出扩展必须带 token;tests/e2e/bridge-extension.e2e.spec.ts)在本机真实 Chromium 上跑通 2 个用例:构建出的扩展确实派生出固定 id 并仅凭 Origin 完成免 tokenhello,另一例走配对 token。node scripts/smoke-runtime.mjs:通过(真机 dsh web,全链路)。影响范围 / Impact
key落地后扩展 id 会变一次,按 id 存的设置(远程桥地址、token)需重新填写——README 与两个安装脚本已注明;重跑scripts/install.sh并重启 dsh 生效。moz-extension://Origin 一直是每次安装的 UUID,本来就必须带 token,行为不变。changelog
* 2026-10-19 [Fix] 安全修复:本机免 token 连接现在只授予本应用自己的扩展(扩展 id 随安装包固定),其它已安装扩展必须携带 token;从旧构建升级时扩展 id 会变更一次(感谢 @chintoleung)。* 2026-10-19 [Fix] Security fix: tokenless loopback access is now granted only to this extension (its id is pinned by the installation), so other installed extensions must present the token; upgrading from an older build changes the id once (thanks @chintoleung).Checklist
pnpm run build等基础检查 / Passed basic checks