Skip to content

fix(dsl): isolate formula environments - #842

Open
rustytrees wants to merge 1 commit into
indaco:mainfrom
rustytrees:security/dsl-env-confinement
Open

fix(dsl): isolate formula environments#842
rustytrees wants to merge 1 commit into
indaco:mainfrom
rustytrees:security/dsl-env-confinement

Conversation

@rustytrees

@rustytrees rustytrees commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Description

Formula code now sees a small environment made from derived installation paths plus selected build and locale variables. Parent credentials and unrelated shell variables are unavailable through ENV reads and are not inherited by system or safe_popen_read children.

Regression tests cover direct access to MALT_GITHUB_TOKEN and a child process that prints its environment.

Related Issue

Closes #856.

Notes for Reviewers

Before the fix, the focused run had 64 passes and 2 failures. Verification after the fix completed with:

  • Focused DSL builtins: 66 passed
  • zig build test-one: 2,424 passed
  • zig build test: 5,061 passed, 3 skipped
  • zig build: 8 of 8 steps succeeded
  • Commit signature verified with git verify-commit

The first full-suite attempt was interrupted with exit 130 after the local firewall held several test binaries. The retry completed with exit 0 after the firewall was cleared.

Expose only derived installation paths and a small set of build and locale variables to formula code. Apply the same environment to ENV reads, system commands, and captured subprocesses so parent credentials cannot cross the DSL boundary.
@indaco

indaco commented Aug 13, 2026

Copy link
Copy Markdown
Owner

@rustytrees Thanks for the contribution! One small request: could you please instruct your agent to follow the PR template provided in the repository for PRs? It helps keep the PRs consistent and easier to review. Thanks!

@rustytrees

Copy link
Copy Markdown
Contributor Author

I published a runnable PoC for the parent-environment exposure fixed here:

git clone https://github.com/rustytrees/malt-security-pocs.git
cd malt-security-pocs
git checkout bd0e2a4d088cc63c8a7ab1613e851d23808b5a4d
./scripts/run-poc.sh --malt /path/to/malt --expect vulnerable h08

The runner uses malt migrate with an isolated synthetic Homebrew keg because Malt's tap installer does not execute def post_install. It passes the literal canary MALT_POC_SECRET=malt-poc-synthetic-secret; no real credential is used. The formula reaches executeDslPostInstallFields, Interpreter.evalMethodCall, and envGet, then writes the value from ENV["MALT_POC_SECRET"] into its keg.

Exact efd2b99 copied the canary into observed-secret. With the combined patched build containing this PR, migration installed the package but the canary remained unavailable and the file was absent. This PoC covers direct ENV[] access. The child-process regression in the PR remains the coverage for system and safePopenRead inheritance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Security: formula DSL inherits API tokens and unrelated parent credentials

2 participants