Skip to content

Commit 8870526

Browse files
Lokins577claude
andcommitted
fix: _ping 的配置矩阵仅在未配齐时暴露
上一版把每项配置的设置状态无条件暴露在公开端点上,等于替攻击者做侦察 —— 告诉对方哪块功能尚未就绪、值得试探。 改为:配齐后只返回 configured: true,不再输出逐项状态;未配齐时才给缺失项, 而那个阶段站点本来就不可用,这点信息没什么可失去的,却能省下大量排查时间。 同时给这个端点加限流:它要查一次 D1,公开且无鉴权,被刷会白白消耗配额。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent 4cce4aa commit 8870526

1 file changed

Lines changed: 14 additions & 9 deletions

File tree

server/hono/app.ts

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// 错误中间件沿用旧实现的设计:对外只回通用提示 + 错误码 ref,日志记完整信息(脱敏)。
33
import { Hono } from 'hono'
44
import type { AppBindings, Env } from './types'
5+
import { clientIp, rateLimit } from './lib/ratelimit'
56
import modRoutes from './routes/mod'
67
import authRoutes from './routes/auth'
78
import publicRoutes from './routes/public'
@@ -59,9 +60,16 @@ app.onError((err, c) => {
5960
app.get('/healthz', (c) => c.json({ ok: true, ts: new Date().toISOString() }))
6061

6162
app.get('/_ping', async (c) => {
62-
// 只报告「是否已设置」,绝不回显任何值 —— 这是个公开端点。
63-
// 登录链路要求 issuer/clientId/clientSecret/teamId 四项俱全,缺一项就整体
64-
// 降级为「登录未配置」,不这样列出来的话没法判断到底缺哪个。
63+
// 公开端点,加一道限流:它要查一次 D1,被刷会白白消耗配额
64+
const limit = await rateLimit(c.env.KV, `ping:${clientIp(c.req.raw.headers)}`, 30, 60)
65+
if (!limit.ok) return c.json({ ok: false, error: '请求过于频繁' }, 429)
66+
67+
// 逐项状态只报布尔值,且**仅在尚未配置齐全时**返回。
68+
//
69+
// 部署阶段需要它定位缺哪一项(clientSecret 是 secret,不在 wrangler.toml 里,
70+
// 最容易漏);而那个阶段站点本来就不可用,暴露这点信息没什么可失去的。
71+
// 一旦配齐就不再输出 —— 稳定运行的站点没有理由对外公开自己的配置矩阵,
72+
// 那只会告诉攻击者哪块功能尚未就绪、值得试探。
6573
const config = {
6674
PRISM_ISSUER: !!c.env?.PRISM_ISSUER,
6775
PRISM_CLIENT_ID: !!c.env?.PRISM_CLIENT_ID,
@@ -72,16 +80,13 @@ app.get('/_ping', async (c) => {
7280
MOD_LICENSE_PRIVATE_KEY: !!c.env?.MOD_LICENSE_PRIVATE_KEY,
7381
WEBHOOK_SECRET: !!c.env?.WEBHOOK_SECRET,
7482
}
83+
const allConfigured = Object.values(config).every(Boolean)
7584

7685
const out: Record<string, unknown> = {
7786
bindings: { DB: !!c.env?.DB, KV: !!c.env?.KV, R2: !!c.env?.R2 },
78-
config,
79-
loginConfigured:
80-
config.PRISM_ISSUER &&
81-
config.PRISM_CLIENT_ID &&
82-
config.PRISM_CLIENT_SECRET &&
83-
config.PRISM_TEAM_ID,
87+
configured: allConfigured,
8488
}
89+
if (!allConfigured) out.config = config
8590

8691
try {
8792
const r = await c.env.DB.prepare('SELECT COUNT(*) AS n FROM roles').first<{ n: number }>()

0 commit comments

Comments
 (0)