Skip to content

🐛 修正 Firefox USER_SCRIPT 的分離 realm 沙盒相容性 - #1706

Draft
cyfung1031 wants to merge 9 commits into
mainfrom
pr/sandbox-ff-spec-fix
Draft

🐛 修正 Firefox USER_SCRIPT 的分離 realm 沙盒相容性#1706
cyfung1031 wants to merge 9 commits into
mainfrom
pr/sandbox-ff-spec-fix

Conversation

@cyfung1031

@cyfung1031 cyfung1031 commented Aug 30, 2026

Copy link
Copy Markdown
Collaborator

Checklist / 检查清单

  • Fixes mentioned issues / 修复已提及的问题
  • Code reviewed by human / 代码通过人工检查
  • Changes tested / 已完成测试

背景

對應 issue #1701:Firefox 的 USER_SCRIPT world 中,globalThis 與頁面 window 屬於不同 JavaScript realm。原有 sandbox 建模隱含 global === window,因此會把 JavaScript realm 的 intrinsic、頁面 Window 的 DOM/WebIDL 成員,以及 userscript 自己的 global 混在同一條 descriptor chain 中。

這會造成 window/self/globalThis alias 不一致、DOM/EventTarget method receiver 錯誤,以及 NodeNodeFilterXMLHttpRequest 等 constructor/interface 的 prototype 或 static properties 在 bind 後遺失。

本次改動

  • 將 descriptor snapshot 明確拆成三個角色:
    • realmGlobal:保留 userscript realm 的 JavaScript intrinsics,且只收集 own properties。
    • hostWindow:提供 DOM、Window accessor、EventTarget method 與必要的 host constructor。
    • scriptGlobal:userscript 實際看到的 sandbox global。
  • 以 dual-source descriptor model 收集 host Window prototype 與明確允許的 host members,避免把一般頁面 own properties 批量洩漏到 sandbox。
  • windowselfglobalThistopparentframes 維持 sandbox identity。
  • 綁定需要 host receiver 的 method 到 hostWindow,同時保留 constructor/interface 的 prototype 與 static properties,避免 brand check 與 static constant 失效。
  • 整理 descriptor snapshot 的階段與 precedence,補回每個階段的維護註釋。
  • 補充 split-realm、host receiver、constructor/static identity、事件 lifecycle、sandbox isolation 與 page-global isolation 的 regression tests。
  • 維持 Chrome 路徑的既有行為,Firefox 以 globalThis !== window 的實際結構來決定 split-realm 行為,不依賴瀏覽器名稱判斷。

實現考慮

descriptor 的來源順序固定為:

realmGlobal own propertieshostWindow prototype chainhost event properties明確 whitelist forwarding

先處理的 realm/子類 descriptor 優先,避免後續父類 descriptor 覆蓋;host Window 的一般 own properties 不會被批量複製。需要 receiver 的 host function 會使用 hostWindow,而 interface/constructor 則保留原本的 callable、prototype 與 static surface。

事件 property 維持既有 lifecycle 契約:註冊與移除作用在同一個 hostWindow,callback 的 this 仍然是 sandbox;primitive handler、function 替換/清除與 object handler 都有測試覆蓋。

已知限制

  • 本 PR 聚焦 createProxyContext() 的 dual-source sandbox model;沒有改變 @grant none 是否建立 sandbox 的既有 policy。
  • 測試使用 split-realm fixture,尚未在真實 Firefox Cu.Sandbox / Xray runtime 中手動驗證。
  • 完整 suite 在目前 sandbox 環境中有一個與本次變更無關的環境限制:tests/verification-tools.test.mjs 嘗試監聽 127.0.0.1 時收到 listen EPERM,結果為 343/344 test files、4316/4317 tests 通過。
  • onurlchange custom roots 與所有 host whitelist 成員尚未各自建立完整 browser coverage。

建議審查重點

  • Firefox split-realm 下的 descriptor source、host receiver 與 DOM/EventTarget brand check。
  • constructor/interface 的 prototype 與 static identity 是否保留。
  • host own property 不洩漏、sandbox self-reference 與跨 sandbox global isolation。
  • on* event property 的 register/remove/replace lifecycle。
  • descriptor precedence 與維護註釋是否足以支撐後續新增 host API。

參考

驗證

  • pnpm exec vitest run src/app/service/content/create_context.test.ts src/app/service/content/exec_script.test.ts src/app/service/content/exec_warp.test.ts --reporter=dot — 3 files / 72 tests passed
  • pnpm run typecheck — passed
  • pnpm run lint — passed
  • pnpm exec eslint . --cache --cache-location .eslintcache — passed
  • pnpm exec prettier --check src/app/service/content/create_context.ts — passed
  • pnpm run test:ci — 343/344 files、4316/4317 tests passed;唯一失敗為上述 localhost EPERM 環境限制

@cyfung1031 cyfung1031 linked an issue Aug 30, 2026 that may be closed by this pull request
@cyfung1031 cyfung1031 changed the title fix sandbox ff spec 🐛 修正 Firefox USER_SCRIPT 的分離 realm 沙盒相容性 Aug 30, 2026
@CodFrm

CodFrm commented Aug 31, 2026

Copy link
Copy Markdown
Member

改动这么大吗,很担心会产生回归问题

@cyfung1031

Copy link
Copy Markdown
Collaborator Author

改动这么大吗,很担心会产生回归问题

看過是合理的。但要人手仔細檢查
等多兩週吧

@CodFrm

CodFrm commented Aug 31, 2026

Copy link
Copy Markdown
Member

改动这么大吗,很担心会产生回归问题

看過是合理的。但要人手仔細檢查 等多兩週吧

#1697 的呢?也能解决这个问题,这个pr是为了更干净的重构修复?

如果是的话 这个 pr 我觉得可以等下个大版本的beta再更新和验证,现在我先将1.5.0转正式版本了

@cyfung1031

Copy link
Copy Markdown
Collaborator Author

改动这么大吗,很担心会产生回归问题

看過是合理的。但要人手仔細檢查 等多兩週吧

#1697 的呢?也能解决这个问题,这个pr是为了更干净的重构修复?

如果是的话 这个 pr 我觉得可以等下个大版本的beta再更新和验证,现在我先将1.5.0转正式版本了

Firefox 版的Bug肯定會有的。Firefox底層用xray, 跟chrome不一樣。
轉不轉正式版沒意見

沙盒問題不必急於修正
如果修正只是表面的而不是正確處理,日後又要在錯誤的基礎上砌積木
對agent來說在錯誤的基礎上砌積木是很難
它會把錯誤的基礎當成真相,然後一直糊塗下去

我有看過1697 . 那個看起來只有結果正確。
先保留吧

@CodFrm

CodFrm commented Aug 31, 2026

Copy link
Copy Markdown
Member

改动这么大吗,很担心会产生回归问题

看過是合理的。但要人手仔細檢查 等多兩週吧

#1697 的呢?也能解决这个问题,这个pr是为了更干净的重构修复?
如果是的话 这个 pr 我觉得可以等下个大版本的beta再更新和验证,现在我先将1.5.0转正式版本了

Firefox 版的Bug肯定會有的。Firefox底層用xray, 跟chrome不一樣。 轉不轉正式版沒意見

沙盒問題不必急於修正 如果修正只是表面的而不是正確處理,日後又要在錯誤的基礎上砌積木 對agent來說在錯誤的基礎上砌積木是很難 它會把錯誤的基礎當成真相,然後一直糊塗下去

我有看過1697 . 那個看起來只有結果正確。 先保留吧

#1697 不修的话,Firefox无法正常使用,我先合了 #1697

这个留到下个版本验证吧,肯定是要干净的处理的,#1697 相当于是一个临时方案

不过说实话,我对这块不熟,交给你啦 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Proposal] 在原沙盒基礎上修正Firefox Spec問題

2 participants