dshbase

插件目录 / Developer / dsh-trusted-host-proxy-403-fix

dsh-trusted-host-proxy-403-fix

已验证 · 实测可装 roojay

✓ 持续维护 基于 7 个官方 DSH 包

查看 GitHub ↗ ← 返回插件目录

0Stars
0Forks
0未关闭 issue
—语言
2026-08-15最近推送
跨平台平台

功能简介

Developer 类别的 DeepSeek Harness 插件。

✅
我们的评价
可用 — 实测通过,早期项目

Developer 类别的 DeepSeek Harness 插件。 实测能干净安装、正常启动。早期项目,但功能可用。

「已验证」表示我们的自动化 CI 在干净 profile 里实际执行了 dsh plugin add 并启动成功——仅此而已。功能描述与版本兼容性均为作者声明。这不是安全审计,也不代表对第三方代码的背书。

README

dsh-trusted-host-proxy-403-fix

English | 中文

A standalone DeepSeek Harness plugin bundle for the web profile. Version 0.3.0 is pinned to @deepseek-ai/dsh@0.1.1-rc.2.

dsh web (dsh --profile web) listens on the loopback interface. You can repeat --trusted-host to add trusted host entries that pass the /api browser request security checks. Requests to non-privileged API methods then succeed when their Host matches one of those entries.

The Node.js /api handler applies a second check to the privileged method set with an empty trustedHosts list, which restricts these methods to loopback. As a result, a reverse proxy can reach other API methods through a configured host, while these 15 methods remain unavailable. When the proxy preserves the public Host header, Settings → Models fails with:

transport failure for /api/settings.describe: HTTP 403

This plugin registers an exact /api/<method> route for each privileged method and validates those requests against the same trustedHosts list as the rest of /api. It keeps the official connection plugin in place and does not provide authentication. The official host checks control which hostnames may reach the API; they do not verify user identity. The Web transport has no built-in authentication.

Before you install

After installation, requests using any host listed in trustedHosts can call the methods below. These methods can read and change settings and credentials, open native directory dialogs, manage agent presets, and make the DSH host send a model discovery request to a URL supplied by the caller.

Install this plugin only when those hosts are already protected by authentication or equivalent network isolation.

  1. Add only the hosts that clients use to --trusted-host. Each entry must be a canonical host[:port] value without a scheme, path, user information, or wildcard.
  2. Protect those hosts with authentication or network isolation. Do not expose dsh web directly to the public internet with this plugin as the only protection. The official CLI still rejects --host 0.0.0.0.
  3. For browser requests, the host and port in Origin must match the Host header. Requests with sec-fetch-site: cross-site or Origin: null are rejected.
  4. Do not rewrite Host to a loopback address while keeping the public HTTPS origin. That mismatch also causes the rest of /api to return 403.
  5. User authentication and authorization remain outside this plugin.

Privileged methods

This is the complete official PRIVILEGED_METHODS list in @deepseek-ai/dsh-client-connection 0.1.1-rc.2. All other /api routes keep the default dsh-web-app behavior.

Method Purpose
/api/settings.describe Read all exposed settings namespaces
/api/settings.openDocument Open the settings document
/api/settings.update Update settings
/api/settings.replace Replace a settings document
/api/settings.mutate Modify settings
/api/credentials.describe Check whether a credential is configured and where it comes from
/api/credentials.set Save a credential
/api/credentials.unset Remove a credential
/api/llm.discoverModels Send a model discovery request from the DSH host using credentials supplied by the caller
/api/host.pickDirectory Open the native directory picker
/api/host.openPath Open a path on the DSH host
/api/agentPreset.read Read an agent preset definition
/api/agentPreset.copy Copy an agent preset
/api/agentPreset.remove Remove an agent preset
/api/agentPreset.openDocument Open an agent preset document

The following methods are not part of this list and remain unchanged: /api/llm.providers, /api/llm.models, /api/host.describe, /api/agentPreset.list, /api/agentPreset.select, session.create, /api/events.mux, and /api/events.host.

Release an updated plugin version if the official privileged method list changes.

Settings persistence for trusted hosts

The 403 fix above unblocks the privileged RPCs, but DSH 0.1.1-rc.2 still treats
a non-loopback page as untrusted. Its shared settings mirror starts in the
terminal unavailable state, so Settings → Models reports settings are unavailable in this browser; per-namespace settings scopes also use "memory"
persistence and silently drop choices on reload.

This package's browser half upgrades the authenticated trusted-host deployment
to host persistence:

  • It promotes the shared connection.isLoopback capability for the client
    graph loaded from this same trusted-host plugin row. Future settings scopes
    are consequently created in host mode.
  • It upgrades the shared settings describe mirror from memory to host mode and
    calls load() so an already-terminal unavailable mirror performs the
    privileged read and populates Settings → Models.
  • It upgrades the controllers reachable through the locale and theme
    services in place (persistence is a plain instance field) and triggers a
    reload, so a saved preference applies on the first paint after the upgrade
    without waiting for the user to pick it again.

The browser half is a dsh.client entry shipped from the same row: no
additional configuration is needed. Its DSH package injections and peer
dependencies are all pinned to 0.1.1-rc.2; re-check the official connection,
mirror, and scope implementations before upgrading DSH.

After installing, the Language (and Appearance, Composer Enter) preferences
are written to the settings document (e.g. settings.yaml under the harness
home) and survive page reloads and Web process restarts.

Install

This package uses ESM and has no prepare script, so installing it from Git does not require allowBuilds.

dsh plugin --profile web add github:roojay/dsh-trusted-host-proxy-403-fix#v0.3.0

Install from npm:

dsh plugin --profile web add dsh-trusted-host-proxy-403-fix@0.3.0

Install from a GitHub Release tarball:

dsh plugin --profile web add https://github.com/roojay/dsh-trusted-host-proxy-403-fix/releases/download/v0.3.0/dsh-trusted-host-proxy-403-fix-0.3.0.tgz

Install from a local directory:

cd /absolute/path/to/dsh-trusted-host-proxy-403-fix
pnpm install --ignore-scripts
dsh plugin --profile web add "$PWD"

The dependency installation is required for a local-directory link. Without it, DSH cannot resolve the plugin's peer dependencies when the Web process starts.

dsh web is equivalent to dsh --profile web. Restart the Web process after installation and continue passing the public host when starting it:

dsh web --port 3080 --trusted-host app.example.com

Do not hard-code a host in cordis.patch.yml. Keep trustedHosts set to !!js ctx.webRuntime.trustedHosts.

Remove the plugin:

dsh plugin --profile web remove dsh-trusted-host-proxy-403-fix

Verify

dsh --profile web --dump-config

The merged configuration should contain a # == dsh-trusted-host-proxy-403-fix section. Its trusted-host-proxy-403-fix entry should read trustedHosts from ctx.webRuntime.trustedHosts.

Send a request to the loopback address using the same host passed to --trusted-host:

# before: 403 forbidden
# after:  200 (the RPC response may be invalid-request, but it must not be forbidden)
curl -sS -D- -o /tmp/dsh-body -X POST http://127.0.0.1:3080/api/settings.describe \
  -H 'Host: app.example.com' \
  -H 'Origin: https://app.example.com' \
  -H 'content-type: application/json' \
  -d '{}'

A mismatched Origin must still be 403:

curl -sS -o /dev/null -w '%{http_code}\n' -X POST http://127.0.0.1:3080/api/settings.describe \
  -H 'Host: app.example.com' \
  -H 'Origin: https://evil.example' \
  -H 'content-type: application/json' \
  -d '{}'
# expect 403

After passing the authentication configured in front of DSH, open Settings → Models in the browser. The privileged method should no longer return 403.

Then confirm settings persistence (the 0.3.0 browser half):

  1. Settings → Language: pick zh or en and save.
  2. Check $DSH_HOME/settings.yaml contains locale.preference with that value.
  3. Hard-refresh the page. The language choice must still be there.
  4. Restart dsh web and open the page again. The choice must still be there.

How it works

dsh-host-webserver checks exact routes before prefix routes. This plugin registers one exact /api/<method> route for every privileged method, so those requests bypass the empty trustedHosts check in the official /api handler.

The plugin is pinned to @deepseek-ai/dsh@0.1.1-rc.2. It depends on the official connection service and creates its Fetch handler with createSharedFetchHandler, so its privileged routes are removed whenever the official /api route is removed. API_PATH and Config come from official exports. The request security logic and privileged method list are copied locally because rc.2 does not export them. The request body limit matches the official 300 MiB default, and errors propagate to the official WebServer error handler.

Develop

npm test

License

MIT. The request validation logic is based on @deepseek-ai/dsh-client-connection.

安装

🧩 让 Agent 自动装(推荐)

装一次目录插件,之后本站所有插件都能让 DeepSeek Harness 自动找、自动装:

dsh plugin add dshbase-catalog

然后对 agent 说「帮我装 dsh-trusted-host-proxy-403-fix」,它会在目录里找到并自动安装。文档:dshbase-catalog · 已验证场景包。

该插件是 GitHub 源码(未发 npm)——直接从仓库装:

Web profile:

dsh plugin --profile web add github:roojay/dsh-trusted-host-proxy-403-fix

Headless(CLI)profile:

dsh plugin --profile headless add github:roojay/dsh-trusted-host-proxy-403-fix

实测报告

验证通过:从 GitHub 源码完成 L1 安装 + L2 加载 + L3 运行(dsh 0.1.0-rc.6)。

安全:尚未扫描——我们的每日静态扫描将很快覆盖它。

分享徽章

Developer 里更多

浏览全部 7819 个插件 →