Repository navigation
2.5.1
2.5.1 · 堵住隧道/反代下的管理面提权(安全修复,2026-10-21)
基于什么
2026-10-21 的安全审计报告 §3.1 与 §3.6 定案的两条真 bug(报告:
研究类/安全与界面优化-20261021/安全审计-dsh-remote-bridge.md):
- 高危|远程提权:
/manage/**与回环 admin 头(X-Dsh-Workspace-Admin: 1)的唯一判据
是「TCP 来源是否回环 + Origin 是否回环」。而插件自带的 cloudflared Quick Tunnel 用
--url http://127.0.0.1:PORT转发,公网请求进到 bridge 时remoteAddress恒为 127.0.0.1,
回环校验对隧道流量完全失效。实测无凭据POST /manage/pairings→ 201 → 兑换出完整设备令牌
(scopes 含files.write);GET /manage/roots直接吐全部授权根的绝对路径。
同类拓扑:ngrok、frp、Caddy/Nginxproxy_pass 127.0.0.1、SSH 端口转发、Tailscale Serve。
放大器另有两条:isLoopbackOrigin(undefined) === true(curl 天然不带 Origin 即为「同源」),
以及 Host 头完全没人校验(DNS 重绑定不设防)。 - 中危|
.heif交接图 100% 打不开:写盘表把image/heif映射成扩展名heif,
读取表把heif声明成image/heif,而嗅探器对 ISO-BMFF 的hei*/hev*/mif*一律返回
image/heic;一致性校验要求完全相等,于是恒 415。
干了什么
src/host/auth.ts:新增统一判据adminRefusal/isLocalAdminRequest,
四层纵深(0 隧道运行中整体拒 → 1 出现任何转发头按代理拒 → 2Host必须回环、缺失也拒 →
3 socket 与 Origin 回环)。requireAdmin与principal({allowAdmin})共用同一份,
并各自给出分明的错误码:TUNNEL_MODE_ADMIN_DISABLED/ADMIN_PROXY_FORWARDED/
ADMIN_HOST_NOT_LOOPBACK/ADMIN_LOOPBACK_REQUIRED(后者是 2.5.0 就有的码,
安卓端只消费它的文案,保留作兜底)。
Origin缺失仍然放行,这是刻意的:它不再是信任来源,真正确立信任的是判据 0/1/2;
翻严只会打死curl与本机脚本调试,挡不住隧道(隧道流量先撞判据 0)。理由写进了源码注释。src/host/cloudflared.ts:新增tunnelActivegetter(与publicState.running
同一个表达式),作为判据 0 的真相来源。src/index.ts:把CloudflaredTunnelManager的创建提前到AuthService之前,
并以闭包() => tunnels.tunnelActive注入 —— 请求时刻现读,隧道后来启停也能跟上。src/host/router.ts:解掉「隧道一开,面板连隧道状态都读不到」的自相矛盾。
TUNNEL_MODE_EXEMPT_PATHS让GET /manage/cloudflare/status|activity豁免判据 0
(供本机面板读「隧道开着」;判据 1/2/3 照旧生效,所以隧道来源连这两个端点也 403、
读不到隧道地址 —— 「远程读得到 running 但读不到 url」被明确否决,那要在判据 1 上再开口子)。- 判据 1 增加了 Cloudflare 边缘头(
Cf-Connecting-IP/Cf-Ray/Cf-IpCountry/Cf-Visitor):
因为 cloudflared 的httpHostHeader默认为空、会把Host改写成回环地址,真实隧道下
判据 2 挡不住它。实测确认(只改 Host 能拿到 200,加边缘头才被挡)。 src/host/image-handoff.ts:一致性校验改为按图片家族比较(sameImageFamily),
image/heic与image/heif同族放行。没有让嗅探器伪造image/heif——
HEIC/HEIF 在字节层无法区分,让嗅探器返回它无法自证的值等于让内容自证这道闸门说谎。
跨家族错配(png 字节配.jpg名、heic 字节配.avif名)仍然全部 415。- 版本:
package.json与src/shared/version.ts同步 2.5.0 → 2.5.1(安全修复,patch 版);
OpenAPI / AsyncAPI 的info.version同步。
测了什么
tests/admin-loopback-escalation.spec.ts:原有 5 个it.fails全部改回it并真实通过;
文件从 6 例扩到 16 例,新增:判据 0 的整体拒绝、桌面端(回环 Origin + 回环 Host +
admin 头)仍然放行、隧道状态可读但url被隐去、转发头被拒、
requireAdmin与principal({allowAdmin})对同一请求结论一致、判据矩阵(纯函数层,
含四种码与「允许缺 Origin、绝不允许缺 Host」)。tests/handoff-extension-consistency.spec.ts:.heif由「断言 415」改为「断言 200」,
并保留「嗅探器永远不会返回image/heif」这条根因断言(现在它是性质而非 bug)。tests/security.spec.ts/tests/http-api.spec.ts:按新契约更新(转发头场景由 401 改 403 并断言码)。- 全量:47 个测试文件 / 396 个用例 / 0 失败 / 0 expected fail(修复前 386 例含 5 个 expected fail)。
typecheck与docs:check均通过。