DSH HUB
HomePlugin StorePlugin PacksCommunityRankingsResourcesPublish Guide
Plugin source
Back to catalog

Vladimir-Kryshchenko /

Vladimir-Kryshchenko/dsh-route-fence-linter

Verified

Static linter for DeepSeek Harness plugin HTTP routes: every webServer route bypasses the /api gateway's trust check and must pin the Host to loopback itself. PASS/WARN/FAIL per route, as a CLI and a dsh tool.

★ 0 Stars0 Forks0 IssuesN/A Community rating0 Confirmed installs
View on GitHub
READMESource: master@cef3b039

dsh-route-fence-linter

Every plugin route registered on webServer is dispatched by longest-prefix match, ahead of the host's /api gateway — so it never passes the gateway's unified trust check. Each plugin author must ship their own browser-trust fence, and most do not. This linter finds the ones that did not.

Usage

dsh-route-fence scan                       # $DSH_HOME/profiles/web
dsh-route-fence scan /path/to/profile

Exit codes: 0 clean · 1 at least one FAIL · 2 usage/IO error.

Verdicts

Verdict Meaning
PASS The handler gates on a fence that pins the Host before Origin handling.
WARN Inside the fence, Origin / sec-fetch-site is read before the Host is pinned. Confirm the ordering by hand.
FAIL One of: no Host check anywhere; a fence that compares Origin to Host but never pins the Host to loopback (bypassable by DNS rebinding — the attacker controls both headers and they match); or a fence that exists but this handler never calls.

Bundles whose sources cannot be read are reported as SKIP and counted in the summary — a skipped bundle is not a clean bundle.

Scan scope

The scan covers what a package publishes (its package.json files field); a package that declares no files is scanned whole. Anything excluded is named in the output as a note line, never dropped silently.

Scoping by directory name was tried and reverted: skipping anything called tests/ or examples/ would have let a plugin hide an unfenced route in a directory with that name and be reported clean. Publication scope cannot be gamed that way — the loader can only import what was installed.

The rebinding-bypassable shape is graded FAIL, not WARN: it was found live in a real, widely-installed plugin and confirmed exploitable against a running profile — a request with Host: evil.example and Origin: http://evil.example passed the check and executed a state-changing method.

The fence this checks for

The shape the host itself uses (and dsh-better-sidebar/src/trust-fence.ts copies): pin the Host header to loopback or a configured trusted authority first, refuse cross-site fetch markers, and only then compare Origin. Comparing Origin before pinning the Host is not a fence.

Limits

Heuristic over source text, not dataflow analysis. A fence is identified as the smallest function body that both references the Host and constrains it; a handler counts as gated when it calls that fence, receives it as a value, or performs the check inline. This recognises the reference implementation, the threaded-fence pattern, and helper-based Host reads — but a sufficiently indirect fence can still be missed. Report false verdicts; they are bugs.

—/ 5

No ratings yet

Verified DSH bundle

Commit cef3b0395e81

Community comments

No comments yet. Be the first to write one.

DSH HUB

A community index for DSH plugins. Not an official GitHub or DeepSeek AI product.

CommunityResourcesAPIAbout