[security] fix: reject empty env allow wildcards#78
Merged
steipete merged 1 commit intoMay 11, 2026
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR hardens Crabbox's environment-variable forwarding boundary so a bare wildcard allow pattern cannot silently forward every local environment variable to a remote lease.
env.allow: ['*']/ empty-prefix wildcard patterns in the env allowlist matcher.CIand non-empty prefix wildcards such asPROJECT_*..crabbox.yamlconfig path.Security issues covered
env.allowwildcard forwards all local environment variablesBefore this PR
crabbox.yaml/.crabbox.yaml.env.allowvalues ending in*were treated as prefix wildcards.*produced an empty prefix, and every environment-variable name has that prefix.allowedEnv()copied all matching values fromos.Environ().After this PR
.crabbox.yamlattemptingenv.allow: ['*'].Why this matters
Crabbox's security docs describe environment forwarding as allowlisted and state that secrets should stay local unless explicitly allowed. Repo-local config is controlled by the repository being run, not necessarily by the operator. A repository-controlled
env.allow: ['*']therefore turns a convenience setting into a local secret exfiltration primitive.Attack flow
Affected code
internal/cli/repo.go,internal/cli/config.go,internal/cli/run.go,internal/cli/ssh.gointernal/cli/ssh_test.go,internal/cli/config_test.goRoot cause
Bare
env.allowwildcard forwards all local environment variables:envAllowed()accepted any pattern ending in*and passedstrings.TrimSuffix(pattern, "*")directly tostrings.HasPrefix().*, the prefix is empty, so every local environment variable matched, including secret-looking values the operator did not individually allow.CVSS assessment
CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:NRationale:
Safe reproduction steps
In a Crabbox checkout before this fix, create a temporary repository directory containing:
Set a proof environment variable, for example:
export CRABBOX_PROOF_API_TOKEN=critical-secret-valueLoad Crabbox config from inside that repository and inspect
allowedEnv(cfg.EnvAllow).Observe that the proof variable is included even though it was not individually allowlisted.
Build a remote command with
remoteCommandWithEnvFile()and observe the proof variable serialized into the command prefix.The regression test added in this PR performs the same check without contacting a remote provider.
Expected vulnerable behavior
envAllowed("CRABBOX_PROOF_API_TOKEN", []string{"*"})returned true..crabbox.yamlwithenv.allow: ['*']causedallowedEnv(cfg.EnvAllow)to include the local proof token.Changes in this PR
envAllowed()before applying prefix wildcard matching.*patterns..crabbox.yamlwithenv.allow: ['*'].Files changed
internal/cli/repo.gointernal/cli/ssh_test.go*no longer matches all variables andPROJECT_*still works.internal/cli/config_test.goenv.allow: ['*']does not forward a proof secret.Maintainer impact
Fix rationale
A wildcard matcher should never treat an empty prefix as authorization to forward every local environment variable. Requiring wildcard prefixes to be non-empty keeps the documented allowlist behavior useful while preventing the broadest repo-controlled secret forwarding case.
Type of change
Test plan
Executed with:
Token usage
Disclosure notes
env.allowpattern; it removes the broad empty-prefix wildcard behavior while preserving explicit allowlist functionality.