
Security News
Deno Goes the Way of the Dinosaur
Cloudflare is acquiring Deno’s team, which will provide another year of bug fixes and security updates before ending support for the runtime.
dsh-web-pass
Advanced tools
DSH web-password gate: multi-password multi-upstream reverse proxy (one password, one backend; add upstreams from the settings page) + forced first-time setup + Settings 'Web password' tab + 2-day sliding sessions + size-capped access log + non-loopback s
/api/<endpoint> exact Fetch route,不再占用共享 /api interceptor,会话列表等普通 API 恢复正常。ReferenceError(调用了不存在的 writePasswordFile)。host:port 删除后再新增,现在复用原条目序号,不再报错。client-connection 模块改写之外,另加 __DSH_TRANSPORT__.ownsHost 前置垫片双保险。不改动已有密码、上游条目或会话数据。
简体中文 | English
一个零依赖的 DeepSeek Harness Web 插件:在 DSH 前面加一道网页密码门,并支持一密码一后端的多入口分流。
浏览器 → (TLS / 反向代理) → dsh-web-pass :3081 ┬→ 127.0.0.1:3080(主人 DSH,装本插件)
├→ 127.0.0.1:3085(访客干净 DSH,可选)
└→ 127.0.0.1:5101(openclaw、fnOS 等本地服务,可选)
认证与会话
/gate/logout 只接受 POST(防 Logout CSRF)。多密码多上游(访客模式,v0.3.2)
upstreams.json,重启保留,patch 行照旧可用。对 DSH 的增强
日志与可观测
/dsh-logs/:只记录密码验证相关请求,按大小轮转(默认 1MB × 7 份),体积有硬上限;IP 用 HMAC-SHA256 假名化 + 网络前缀,不落原始 IP。v0.3.4 修复
X-Frame-Options: DENY 等安全头(本意是保护登录页),会把 fnOS 等后端用同源 iframe 嵌套件应用的页面整页挡成「拒绝连接」——Docker / 套件经门全空白即此因。现在这些头只作用于门自身页面(登录页 / 日志页),代理响应还原为上游原始响应头;上游自带的安全头照常生效。v0.3.5 安全加固
loginLockMs × 退避倍数,连续触发按 2× 递增(至多 16×);退避倍数在锁到期后保留,静默 1 小时无失败才回到 1×;锁定期内的试探不计失败、不延长锁定。text/html 自动降级为流式透传(放弃注入),客户端中途断开立即掐断上游——防把与 DSH 同进程的门拖 OOM。dws_session 不再随请求 / WebSocket 握手发给任何上游(旧版会原样转发给 dsh:false 上游)。/gate/setup 必须携带 GET /gate-setup 下发的 HttpOnly cookie,跨站自动提交表单无法抢注密码门。host:port;patch 调整行序 / 改端口重启后旧会话自动作废(无需再手动清 sessions.jsonl)。升级到 v0.3.5 后需重新登录一次。resolveEntries 对 patch 行 host:port 查重。lib/ 按领域拆为 9 个内聚模块(proxy 转发核心 / index 装配+RPC / 条目表 / 会话存储 / 门页面 / 代持 / 日志 / 密码学 / 限速器 / 数据目录),合并重复实现;对外导出面不变,纯代码搬家零行为变更。v0.3.6 安全加固(hardening,无新功能、无数据迁移)
dws_session / dws_setup 在透传、改写、WebSocket 握手三个出口统一过滤(sanitizeUpstreamSetCookie),上游只能写自己的业务 Cookie。Forwarded / X-Forwarded-* / X-Real-IP 等一律丢弃,由门按 trustProxy 重建规范值(默认只信 socket 直连地址;可信前代后取左端值)——上游看到的不再是可伪造的客户端断言。GET /gate/logout 返回 405(防 Logout CSRF),退出浮标改走 POST。v0.3.7 修复与兼容(DSH v0.1.5-rc.1)
/api interceptor:原实现把处理函数注册成共享 /api 通道的唯一 interceptor,而 DSH 0.1.5 的 API Gateway 也依赖该入口——结果普通 /api 请求(尤其会话列表)无法落到 Gateway fallback。现在每个 endpoint 独占一条 POST /api/<endpoint> exact Fetch route(ctx.connection.fetch.register),照常经过 Connection 的 Host/Origin 与浏览器认证,其余 API 不受影响。setPasswordHash 调用了从未定义也从未导入的 writePasswordFile(v0.3.5 模块化拆分时漏改),因此设置页改密码与首次强制设密都会抛 ReferenceError,被错误处理吞成一句提示。已修正为 writePasswordHash。host:port 去重,于是同一地址删除后再新增会被跳过并报「运行时上游未加入内存条目表」。现在改为复用原条目序号并解除软删——顺序、序号(会话绑定键)都不变;与 patch 行地址冲突时明确报错。client-connection 模块定向改写外,另在页面 <head> 注入前置垫片把 __DSH_TRANSPORT__.ownsHost 置真(早于所有客户端模块求值);改写匹配同时放宽到整条 dsh-client-connection 路径。插件仓库里不落任何运行时数据——数据都在
$DSH_HOME/dsh-web-pass/(密码哈希、会话、日志)。
插件在 dsh web 进程内部运行一个反向代理:把 Host/Origin 改写为回环地址,从而不改任何 DSH 配置就能通过 DSH 的浏览器信任检查,并在其上叠加 cookie 密码认证。TLS 通常由上游终止(反向代理 / 隧道 / nginx)。
accept-encoding,上游以明文回(nginx 等默认开 gzip 会让注入整体跳过——polyfill / 模块改写 / 退出浮标全依赖明文),压缩交给门前面的反向代理做。dsh: true 的后端:代持 DSH 认证 + 定向改写 client-connection 模块(见下文两节)。dsh: false 的后端(fnOS、openclaw 等):原样透传,不带 DSH cookie,也不强加安全头。方式一:从 npm 安装(推荐)
dsh plugin --profile web add dsh-web-pass
# 然后重启 dsh web
方式二:从源码安装
git clone https://github.com/linz919/dsh-web-pass.git
dsh plugin --profile web add ./dsh-web-pass -w
# 然后重启 dsh web
确认已加载:
ss -tln | grep -E ':3081|:3082'
所有选项都有内置默认值——完全不写任何配置也能正常工作(日志轮转默认即 1MB × 7 份)。即使 cordis.patch.yml 在安装其他插件时被覆盖、丢失自定义配置,功能也不受影响:日志轮转回落到内置默认,访问密码的环境变量名回落到内置的 DSH_WEB_PASS_PASSWORD。
来自插件配置(cordis.patch.yml 的 config 段,可选):
| 选项 | 默认值 | 说明 |
|---|---|---|
port | 3081 | 反向代理监听端口 |
logViewerPort | 3082 | 内嵌日志查看器端口 |
maxLoginAttempts | 3 | 锁定前允许的密码错误次数 |
loginLockMs | 60000 | 真锁定基准时长(毫秒,自最后一次失败起计;连续触发按 2× 递增至 16×) |
passwordEnv | DSH_WEB_PASS_PASSWORD | 提供密码的环境变量名 |
trustProxy | false | 是否信任 X-Forwarded-For / CF-Connecting-IP 头(用于访客 IP 识别与登录限速) |
clientHostTrust | true | 非 loopback 页面(IP/域名访问)也启用 Host 设置文档;false 恢复 DSH 原生行为(仅 localhost 可见设置内容) |
logMaxBytes | 1048576 | 访问日志单文件大小上限(字节),达到即轮转,下限 64KB |
logMaxFiles | 7 | 轮转后保留的历史文件份数(access.log.1 … access.log.N),超出自动删除 |
upstreams | [] | 多密码多上游表(见下文):每条含 label / passwordEnv / host / port / clientHostTrust / dsh / enabled;不配即单密码行为 |
关于
trustProxy:默认关闭时,访客 IP 与登录限速只依据 socket 直连地址——客户端伪造任何转发头都不被采纳。开启后取X-Forwarded-For/CF-Connecting-IP作为限速键,因此仅当网关前面部署了会覆写这些头的可信反代(nginx 配proxy_set_header X-Forwarded-For $remote_addr;、Cloudflare 隧道等)时才开启;反代若只是透传,伪造 XFF 等于给攻击者无限个限速键。
DSH_WEB_PASS_PASSWORD,设到 dsh web 服务进程环境里)> 文件 $DSH_HOME/dsh-web-pass/password(管理员条目)或 password.<i>(第 i 条,scrypt 哈希)。cordis.patch.yml 只引用环境变量名——绝不要把密码明文写进去(该文件会进 git / 仓库)。sessions.jsonl 一起删更干净)即回强制设置页;用了环境变量的先 unset 再重起。cordis.patch.yml 的 upstreams 加一条后重起 dsh web。页面上新增的行保存在 $DSH_HOME/dsh-web-pass/upstreams.json(0600,重启保留),与 patch 行共存、追加在其后;密码值可在设置页「网页密码」活改,不用重起。patch 里删行重起则彻底消失;管理员条目不可停用、不可删除。删除过的地址可以再次新增——会复用原条目序号并解除软删,不会重复占位,也不影响其它条目已绑定的会话;若与 patch 行地址相同则明确报错。clientHostTrust 保持 false(默认),访客设置页空白、改不了模型。门只管转,不管起——后端自己跑起来、只绑 127.0.0.1。dsh: true 的条目各持一份 DSH cookie 并可改写模块;反代 openclaw、fnOS 等非 DSH 服务请设 dsh: false(默认),原样透传,免得把 DSH cookie 带过去。/dsh-logs/)只存在于装了本插件的主 DSH;访客干净间不装本插件,访客碰不到管理面。-),可按条目筛选。host:port,校验时两者必须同时匹配——手工调整 patch 行序、改端口后重起,旧会话自动作废(各端重新登录即可,不再需要手动清 sessions.jsonl)。顺序仍为「管理员 → patch 行 → 页面新增行」,只追加、软删保序。DSH Web 自带一层浏览器认证(进程 launch-token 换 30 天 cookie)。本插件运行在 dsh web 进程内部,可经 ctx.connection.authenticatedUrl() 拿到带 process-token 的 URL,内部换取 DSH 的持久 cookie 后,注入所有转发到上游的请求与 WebSocket 握手——因此经密码门进入的浏览者永远看不到 DSH 的 "authentication required"。
dshAuthHolding 字段(是否已代持 DSH cookie)。dsh web 提供 ctx.connection 即自动启用;不可用时回退为旧行为(浏览者仍需 DSH token)。DSH 客户端只在页面地址为 localhost/127.x 时才挂载宿主设置文档;经局域网 IP 或域名访问(包括走本密码门)时,设置一律降级为内存模式——设置里的「插件配置」「模型」「常规」等标签页会整页空白(插件清单、聊天等纯 RPC 功能不受影响)。
本插件用两道措施把该判定补为恒真:① 在代理层对 DSH 下发的 client-connection 模块做一次定向改写;② 在页面 <head> 后注入前置垫片,把 __DSH_TRANSPORT__.ownsHost 置真(早于所有客户端模块求值)。设置页在 3081(LAN IP / 公网域名)下完整可用;浏览器地址不变,密码门仍是唯一入口,服务端 /api 的信任校验不受影响。
clientHostTrust: false 恢复 DSH 原生行为。cache-control: no-cache 下发。从旧版本升级后每台设备需强刷一次(Ctrl+F5)——旧模块此前按 immutable 缓存一年,普通刷新不会回源;强刷一次后即自动保持最新。/dsh-logs/(也可从设置页「访问日志」按钮打开):只记录 /gate-login、/gate/setup、/gate/logout 的请求,按「方法 + 路径 + 状态码」判定语义:
$DSH_HOME/dsh-web-pass/access.log —— 按大小轮转:单文件达到 logMaxBytes(默认 1MB)就滚动为 access.log.1,更早的依次后移为 access.log.2 …,最多保留 logMaxFiles 份(默认 7 份),最旧的自动删除。日志总体积因此有硬上限(默认约 8MB),不会随时间无限增长。.hmac-key(自动生成,0600 权限);不要删除它,否则同一 IP 会产生新的假名,聚合分析断档。X-Frame-Options: DENY 等安全头;代理响应不额外加安全头(v0.3.4 起),上游自带的原样生效。trustProxy 开启后改取 X-Forwarded-For / CF-Connecting-IP 作为限速键——只在会覆写这些头的可信反代之后开启,否则等于给攻击者无限个限速键。| 版本 | 要点 |
|---|---|
| v0.3.7 | 兼容 DSH v0.1.5-rc.1:设置页 RPC 迁出共享 /api interceptor,改用 /api/<endpoint> exact Fetch route(会话列表等普通 API 恢复)。修复:改密码 / 首次设密失效(writePasswordFile 未定义);软删过的上游无法再加回(改为复用原条目序号)。增强:__DSH_TRANSPORT__.ownsHost 前置垫片 + 改写匹配放宽;新增上游日志与设置页即时反馈 |
| v0.3.6 | 安全加固:上游回包过滤门保留 Cookie(三出口统一);入向转发头清洗+按 trustProxy 重建;登出仅 POST;吊销落盘失败重试+loud log |
| v0.3.5 | 安全加固:防爆破真锁定+指数退避(成功登录不再清零;退避倍数跨锁保留、静默 1h 重置);注入响应 8MB 缓冲上限+断连中止;转发剥离门会话 cookie;首设一次性令牌;会话绑定上游身份(升级后需重登一次);重登轮换会话;上游超时/请求中止/落盘错误日志。同版完成模块化重构:按领域拆为 9 个内聚模块,纯代码搬家零行为变更 |
| v0.3.4 | 修复:代理响应不再强加安全头(XFO DENY 挡掉 fnOS 同源 iframe 套件页,经门 Docker/套件全空白) |
| v0.3.3 | 设置页直接加上游(即时生效);「🚪 退出」浮标;门剥 accept-encoding 保注入 |
| v0.3.2 | 多密码多上游(访客模式);会话 2 天滑动;日志带条目列 |
| v0.3.1 | 非 loopback 页面解锁 Host 设置 |
| v0.3.0 | DSH 内置认证代持 |
FAQs
DSH web-password gate: multi-password multi-upstream reverse proxy (one password, one backend; add upstreams from the settings page) + forced first-time setup + Settings 'Web password' tab + 2-day sliding sessions + size-capped access log + non-loopback s
The npm package dsh-web-pass receives a total of 12 weekly downloads. As such, dsh-web-pass popularity was classified as not popular.
We found that dsh-web-pass demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.

Security News
Cloudflare is acquiring Deno’s team, which will provide another year of bug fixes and security updates before ending support for the runtime.

Security News
Anthropic’s free OSS Scanner uses Mythos and other Claude models to find open source vulnerabilities and send maintainers reports with proposed fixes.

Security News
On Front Lines’ Early Adopters: CISO podcast, Andrew Becherer shares lessons from Datadog, weighs the long-term costs of AI-built tools, and explains how founders can actually gain a CISO’s trust.