fix(docker): defer to main's Host allowlist and name an unwritable checkout

Two findings from PoBruno's Docker Engine on Linux run (#208), and one from
re-running the suite in the container after rebasing:

- The launcher pinned its own allowedHosts, including '.local'. Vite reads a
  leading dot as a suffix match, so `Host: anything.local` reached the page and
  the data proxies. Main has since moved the policy into build/allowedHosts.js,
  which drops suffix entries on purpose and applies before the app's routes, so
  the launcher's override is deleted rather than patched. As a side effect
  GEV_ALLOWED_HOSTS now also works from `.env`, as it does under `npm run dev`.
- A checkout the container cannot write - typically a clone made as root on a
  NAS or Proxmox host - made Save Keys answer 500 and never created .gev-cache,
  with nothing logged. The launcher now warns at start, naming the owner, the
  ids it runs as, and the two fixes.
- On Docker Desktop the bind-mounted repo always shows an owner other than the
  container user, so git refuses it as "dubious ownership" and the tests that
  shell out to git fail (src/data/bundledJson.test.mjs, new on main). The image
  now marks /app, and only /app, as a safe directory.

Verified in a container on this base: `anything.local` 403 on the page and on
/api routes, localhost 200, GEV_ALLOWED_HOSTS honoured from the environment and
from .env, the warning on a root-owned /app run as 1000:1000, and
bundledJson.test.mjs 6/6.

Reported-by: PoBruno
Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
SM-26andClaude Opus 5.5 committed 2026-10-10 19:48:02 +02:00
1 parent 1c6c291774
commit 79a6a0db5c
4 files changed
+51 -32

No files matched your search

+4 -1
View File
@@ -141,7 +141,10 @@ const LOOPBACK_ADDRESSES = new Set(['127.0.0.1', '::1', '::ffff:127.0.0.1']);
*/
function isTrustedPeerAddress(remoteAddress, env) {
const normalize = (value) =>
String(value || '').trim().toLowerCase().replace(/^::ffff:/, '');
String(value || '')
.trim()
.toLowerCase()
.replace(/^::ffff:/, '');
const address = normalize(remoteAddress);
if (!address) return false;
return String(env?.GEV_KEY_SETUP_TRUSTED_PEERS || '')