Skip to content

Security: isolate production-bundle test execution from CI secrets (vm-escape hardening) #19

Description

@axisrow

Raised during review of #18 (codex findings). The integration test tests/demoscene-bundle.test.mjs fetches the live production Demoscene bundle over HTTPS and executes it in-process via node:vm.runInContext.

The issue: node:vm is explicitly not a security sandbox. Code inside the vm context can recover the host Node process and gain full fs/env/credentials access — e.g. via setTimeout.constructor('return process')(). Reproduced during review (stripping host console does not close the escape; any function in the context exposes the Function constructor).

Exposure: npm test runs in .github/workflows/publish.yml in the same job that mints a write-capable GitHub App token and then performs authenticated git push. A compromise of the Pages deployment (axisrow.github.io/demoscene_classics) could mutate workspace/tooling and capture the App token. On pull_request runs (ci.yml) there are no secrets, so blast radius there is nil.

Accepted residual risk for #18 (bundle is first-party over HTTPS; trade-off weighed against keeping the test a true live regression guard), tracked here as a follow-up rather than a merge blocker.

Suggested fixes (pick one):

  • Pin a content-hash-verified local fixture of the bundle and execute that instead of a network fetch in npm test.
  • Move the live canary into a separate disposable CI job with permissions: contents: read, no secrets, no deployment perms, no writable shared workspace.

Refs #18.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions