fix(loader-client): /env exposes server-only NANOFORGE_SERVER_* variables to the browser

未关闭 适合新手
#132 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

维护者通常 1 天内回复

还没有人认领这个 Issue。

评估

难度
2/5
预计耗时
1-3 小时
新手友好度
77/100
Issue 类型
缺陷
描述清晰度
描述清楚
活跃度
活跃
技术栈
bun, typescript
领域
backend, security

调研方向

从 apps/client/src/env.ts 及其 getGameEnv 函数开始,然后检查对应的 apps/server/src/env.ts 和现有单元测试。添加测试,验证客户端环境输出不包含 NANOFORGE_SERVER_* 值,且服务器输出不包含 NANOFORGE_CLIENT_* 值。完成标准是两个加载器都不公开另一侧带前缀的变量。

由索引模型根据 Issue 内容生成。

描述

app:client app:server bug
Which app is this bug report for?

client

Issue description

Security. /env can return server-only environment variables to any browser that loads the game.

The CLI splits .env into client and server values (NANOFORGE_CLIENT_* / NANOFORGE_SERVER_*), but its runner starts the client loader with { ...process.env, ...clientEnv } (cli runner.ts#L79). So a NANOFORGE_SERVER_* variable exported in the shell or set by CI reaches the client process.

The client loader's getGameEnv keeps every NANOFORGE_* key and /env returns them all, prefix stripped. The server binds to all interfaces, so the value can be read from the local network, not only from localhost.

Reproduced on the local build with a dummy value:

$ NANOFORGE_SERVER_DB_PASSWORD=dummy bun apps/client/dist/server.js -p 39171 -d <empty dir>
$ curl localhost:39171/env
{"SERVER_DB_PASSWORD":"dummy","tlsEnabled":false}

The same happens the other way: the server loader (env.ts) receives NANOFORGE_CLIENT_*.

Expected: /env never returns NANOFORGE_SERVER_* values.

Suggested fix: in apps/client/src/env.ts, drop keys starting with NANOFORGE_SERVER_ (and in apps/server/src/env.ts, drop NANOFORGE_CLIENT_), with a unit test. A follow-up in the CLI can stop the runner from forwarding those prefixes from process.env.

Related to #87 (optional auth on the loader routes): auth would not fix this, since server-only values should never be sent to the client at all.

Found during a read-only audit of main @ 044c766 (2026-11-11).

Code sample
const PREFIX = "NANOFORGE_";

export const getGameEnv = () => {
  return Object.fromEntries(
    Object.entries(process.env)
      .filter(([key]) => key.startsWith(PREFIX)) // NANOFORGE_SERVER_* passes too
      .map(([key, value]) => [key.replace(PREFIX, ""), value]),
  );
};
Versions
  • @nanoforge-dev/loader-client / @nanoforge-dev/loader-server / @nanoforge-dev/loader-website 1.7.0 (main @ 044c766)
  • Bun 1.3.14
  • Linux x86_64
Issue priority

High (immediate attention needed)

I have tested this issue on a development release

044c766

主要语言
TypeScript
星标
1
派生
0
平均合并
17 小时 25 分钟
30 天内合并 PR
11

环境准备

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

NanoForge-dev/Loader 的其他 Issue

查看 NanoForge-dev/Loader 的全部 Issue

相似的 Issue

更多 TypeScript Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。