dsh-cookie-guard:修復 DSH 登錄 Cookie 累積導致 Web UI 打不開

前言

DeepSeek Harness(DSH)桌面端通過瀏覽器 Cookie 做 Web UI 認證。每次啓動往往會換一個新端口,Cookie 名會隨 host:port 變化而變,舊 Cookie 在瀏覽器裏會保留約 30 天,而 DSH 本身不會主動清理。時間一長,同一 127.0.0.1 下會堆出大量 dsh-auth-*,瀏覽器把它們全部塞進 Cookie 請求頭;當累計超過 Node 默認的 16 KiB maxHeaderSize 時,服務器在進入業務邏輯前就返回 431 Request Header Fields Too Large,連清理代碼都跑不到,表現爲 Web UI「永久打不開」。手動清瀏覽器 Cookie 能救一次,但無法從根上阻止再次累積。下面介紹社區插件 dsh-cookie-guard(維護者 bigfatdsh,MIT),它作爲客戶端類 DSH 插件,在 Web 服務器最前面接管大請求頭並下發刪除指令,把問題壓回可控範圍。

這是什麼

dsh-cookie-guard 是安裝在 DSH profile 上的宿主機插件,不修改 DSH 源碼,也不依賴第三方 npm 包。插件 id 爲 cookie-guard,bundle 名爲 dsh-cookie-guard。它針對的是:DSH 瀏覽器認證 Cookie 名形如 dsh-auth-<sha256(host:port) 的 base64url>,只增不清,最終撐爆請求頭。倉庫與說明見 GitHub,社區目錄頁:SkillHub 插件頁。

問題是怎麼發生的

DSH 每次桌面啓動常用新端口,瀏覽器會多寫一條新的 dsh-auth-*;舊條目在有效期內一直存在。瀏覽器對同一 host 發送全部 Cookie,Node 側默認 maxHeaderSize 爲 16 KiB。超過後任意請求(包括首頁)都會在監聽器之前被 431 拒絕。README 中修復前本機實測示例:

GET /  Cookie: big=<20 KB>  ->  431 Request Header Fields Too Large

此時即便插件邏輯寫在 DSH 裏,也進不了 JS 處理器,所以單靠「等 DSH 自己刪 Cookie」無法從已爆頭的狀態恢復。

核心功能

安裝到當前 desktop profile 後,在同一臺正在運行的 GUI 上,README 給出了修復前後對比(節選):

場景 修復前 修復後
20 KB 無效 Cookie 431 401(正常進入認證流程)
約 20 KB Cookie、90 條舊登錄 Cookie 431 200,響應中含 87 條刪除指令
約 34 KB Cookie、150 條舊登錄 Cookie 431 200,響應中含 147 條刪除指令
當前實例的有效 Cookie 200 200,且不會被誤刪

34 KB 場景下,當前有效 Cookie 保留,其餘舊 Cookie 通過 Set-Cookie 帶 Max-Age=0 刪除;請求頭可從約 34 KB 降到約 1 KB。

原理上,插件在 webServer 請求鏈最前面 prependListener,大致四步:

  1. 把監聽器的 maxHeaderSize 提高到可配置上限(默認 256 KiB),讓已超過 16 KiB 的請求能進入 JS。
  2. 用與 DSH 相同的算法算出當前 authority 的 Cookie 名,從 req.headers.cookie 裏剝掉其它 dsh-auth-*,認證代碼只看到當前實例的 Cookie。
  3. 對過期、簽名無效、或超出「當前 + 保留條數」預算的 Cookie,在響應裏追加刪除頭(HttpOnly、SameSite=Strict 等與 DSH 一致)。
  4. 注入方式兼容 writeHead、setHeader、隱式 end(),不覆蓋 DSH 剛簽發的 Cookie。

默認除當前實例外最多保留 3 條其它端口的有效 Cookie,便於多開;只跑單實例時可把保留數設爲 0,代價是其它窗口下次請求可能掉登錄,需重新走 token URL。

安裝與啓用

從 GitHub 安裝(命令來自倉庫 README):

dsh plugin add https://github.com/bigfatdsh/dsh-cookie-guard

README 說明:desktop profile 可通過插件管理器安裝後,依賴形如 dsh-cookie-guard: link:...,並出現在 dsh.profile.bundles 中。插件以 link: 軟鍊形式存在時,改本目錄源碼後重啓 DSH 即生效。

其它 profile(例如 web)需在該 profile 目錄手動 pnpm add link:<本機 dsh-cookie-guard 路徑>,並把 "dsh-cookie-guard" 寫入該 profile package.json 的 dsh.profile.bundles 數組,再重啓 DSH。README 中的示例路徑爲作者本機路徑,你應換成自己機器上的實際路徑。

配置

可在 bundle 的 cordis.patch.yml(或 profile patch)裏覆蓋:

- insert:
    - id: cookie-guard
      name: dsh-cookie-guard
      config:
        maxHeaderBytes: 262144
        keepOtherCookies: 3
        cookieBudgetBytes: 4096
鍵 默認 說明
maxHeaderBytes 262144 監聽器 maxHeaderSize;須大於 16 KiB,範圍 16 KiB–1 MiB。
keepOtherCookies 3 除當前實例外,最多保留幾條其它實例有效 Cookie,範圍 0–8。
cookieBudgetBytes 4096 認證 Cookie 總預算,超出從最舊刪,範圍 256 B–16 KiB。

典型用法與驗證

單元測試(README 稱 22 項,含大請求頭、多 Cookie、401 等):

cd adapted/dsh-cookie-guard
node --test

路徑以你本機克隆或 link 的插件目錄爲準。

對運行中的 GUI 做無副作用探測(把端口換成當前 DSH Web 端口):

python3 - <<'PY'
import urllib.request, urllib.error
req = urllib.request.Request(
    "http://127.0.0.1:51302/",
    headers={"Cookie": "big=" + "a" * 20000},
)
try:
    print(urllib.request.urlopen(req, timeout=5).status)
except urllib.error.HTTPError as e:
    print(e.code, e.reason)
PY

安裝插件後應看到 401 Unauthorized;未修復時爲 431 Request Header Fields Too Large。

適用場景與注意

適合長期用 DSH 桌面端、頻繁重啓或多開端口,且曾在瀏覽器裏堆出大量 127.0.0.1 登錄 Cookie 的開發者。插件與 DSH 同進程權限運行,安裝前建議閱讀 倉庫源碼 與 MIT 許可證,確認符合你的安全策略。

邊界事項(來自 README):

  • 刪除依賴瀏覽器執行標準 Set-Cookie 過期語義;若個別環境不執行刪除,提高後的頭部上限仍可能讓 UI 可用,舊 Cookie 最遲約 30 天過期。
  • 若歷史 Cookie 已超過默認 256 KiB 上限,可把 maxHeaderBytes 調到 1048576 後重啓;仍不行時需在瀏覽器 DevTools 中清一次 127.0.0.1 站點 Cookie,之後由插件接管。
  • 上游若改爲穩定 Cookie 名,插件仍會保留「提高頭部上限 + 清理舊 Cookie」的保險作用,README 認爲不會與上游衝突。

回滾:用插件管理器移除 bundle,或在 profile 目錄從 package.json 去掉依賴與 bundles 條目後 pnpm install 並重啓 DSH。移除後 16 KiB 默認上限恢復,累積問題會再次出現。

DSH 生態強調「一切皆插件」;SkillHub 等社區目錄獨立於 DeepSeek / 幻方,並非官方應用商店。

結尾

dsh-cookie-guard 用監聽器前置處理把「431 永久打不開」變成可進入認證或自動下發刪除指令的正常路徑,並對多開場景保留有限條其它實例 Cookie。需要安裝命令與配置細節時,以 GitHub README 爲準;瀏覽插件元信息可打開 SkillHub 目錄頁。

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜