[Security][Critical] Restrict static serving to public assets #14

Open
opened 2026-07-23 09:27:43 +00:00 by jfig · 0 comments
Owner

Severity

Critical for the documented local deployment mode; partially mitigated in the current Docker image.

Finding

The Node server resolves any request path beneath the application repository root and serves the resulting file. It does not use a dedicated public directory or an explicit asset allowlist.

A safe local validation following the documented npm start mode returned:

  • /.env → 200
  • /.git/config → 200
  • /server.js → 200
  • /package-lock.json → 200
  • /node_modules/ol/package.json → 200

Traversal outside the repository root was correctly blocked, but files inside the root are still exposed. The local mode loads GeoServer credentials from .env, making this a direct credential disclosure.

The current Docker build excludes .env and .git, so those paths return 404 in that container. It still exposes backend source and package metadata because those files exist under the served root.

Relevant code: server.js functions serveStatic and serveFile.

Impact

Any local/non-Docker deployment following the README can disclose GeoServer credentials, repository configuration/history, backend implementation, and future files placed in the project directory. Backend credential disclosure can lead to GeoServer and data compromise.

Resolution proposal

  1. Move browser assets to a dedicated public/ directory.
  2. Resolve static paths relative to that directory only.
  3. Prefer an explicit route/file allowlist for index.html, app.js, styles.css, approved assets, and approved vendor bundles.
  4. Reject dotfiles and directory traversal before filesystem access.
  5. Never place .env, source-control metadata, backend code, lockfiles, or full node_modules under the document root.
  6. Update the Dockerfile and README to use the same safe layout.
  7. Add automated negative-path tests.

Acceptance criteria

  • /.env, /.git/config, /server.js, /package-lock.json, and arbitrary node_modules paths return 404 or 403 in local and Docker modes.
  • Required browser assets still load.
  • The server document root contains no secrets or backend-only files.
  • Encoded traversal and symlink escape tests pass.
  • CI includes the regression tests.
## Severity Critical for the documented local deployment mode; partially mitigated in the current Docker image. ## Finding The Node server resolves any request path beneath the application repository root and serves the resulting file. It does not use a dedicated public directory or an explicit asset allowlist. A safe local validation following the documented `npm start` mode returned: - `/.env` → 200 - `/.git/config` → 200 - `/server.js` → 200 - `/package-lock.json` → 200 - `/node_modules/ol/package.json` → 200 Traversal outside the repository root was correctly blocked, but files inside the root are still exposed. The local mode loads GeoServer credentials from `.env`, making this a direct credential disclosure. The current Docker build excludes `.env` and `.git`, so those paths return 404 in that container. It still exposes backend source and package metadata because those files exist under the served root. Relevant code: `server.js` functions `serveStatic` and `serveFile`. ## Impact Any local/non-Docker deployment following the README can disclose GeoServer credentials, repository configuration/history, backend implementation, and future files placed in the project directory. Backend credential disclosure can lead to GeoServer and data compromise. ## Resolution proposal 1. Move browser assets to a dedicated `public/` directory. 2. Resolve static paths relative to that directory only. 3. Prefer an explicit route/file allowlist for `index.html`, `app.js`, `styles.css`, approved assets, and approved vendor bundles. 4. Reject dotfiles and directory traversal before filesystem access. 5. Never place `.env`, source-control metadata, backend code, lockfiles, or full `node_modules` under the document root. 6. Update the Dockerfile and README to use the same safe layout. 7. Add automated negative-path tests. ## Acceptance criteria - `/.env`, `/.git/config`, `/server.js`, `/package-lock.json`, and arbitrary `node_modules` paths return 404 or 403 in local and Docker modes. - Required browser assets still load. - The server document root contains no secrets or backend-only files. - Encoded traversal and symlink escape tests pass. - CI includes the regression tests.
jfig added the Kind/Security
Priority
Critical
1
Reviewed
Confirmed
1
labels 2026-07-23 09:27:43 +00:00
Sign in to join this conversation.