Summary
Private keys are embedded directly in shell command strings via fmt.Sprintf, making them visible to any user through ps aux, /proc/<pid>/cmdline, or system audit logs.
Affected Files
1. pkg/stacks/thanos/register_candidate.go:619
cmdStr := fmt.Sprintf(
"cd %s && L1_URL=%s PRIVATE_KEY=%s SAFE_WALLET_ADDRESS=%s npx hardhat set-safe-wallet",
sdkPath, t.deployConfig.L1RPCURL, t.deployConfig.AdminPrivateKey, safeWalletAddress,
)
utils.ExecuteCommandStream(ctx, t.logger, "bash", "-c", cmdStr)
The AdminPrivateKey is directly interpolated into the command string passed to bash -c.
2. pkg/stacks/thanos/shutdown.go:206
filteredEnv := []string{
fmt.Sprintf("PRIVATE_KEY=%s", adminKey),
fmt.Sprintf("L1_RPC_URL=%s", s.deployConfig.L1RPCURL),
}
While using env slice is better, the key is still part of the process environment visible via /proc/<pid>/environ.
Attack Scenario
- Attacker has any local shell access (non-root sufficient)
- Runs:
while true; do ps aux | grep PRIVATE_KEY >> /tmp/keys.txt; sleep 0.1; done
- Captures admin private key during
register-candidate or shutdown operations
- Uses key to drain treasury, halt sequencer, or impersonate admin
Severity
CRITICAL — Private key visible in process listing during operation window.
Fix
Replace fmt.Sprintf command strings with exec.Cmd.Env for environment variable injection:
cmd := exec.CommandContext(ctx, "npx", "hardhat", "set-safe-wallet")
cmd.Dir = sdkPath
cmd.Env = append(os.Environ(),
"L1_URL="+t.deployConfig.L1RPCURL,
"PRIVATE_KEY="+t.deployConfig.AdminPrivateKey,
"SAFE_WALLET_ADDRESS="+safeWalletAddress,
)
This keeps keys out of the command-line arguments (not visible in ps aux) while still passing them as environment variables to the child process.
References
- CWE-214: Invocation of Process Using Visible Sensitive Information
- CWE-200: Exposure of Sensitive Information to an Unauthorized Actor
Summary
Private keys are embedded directly in shell command strings via
fmt.Sprintf, making them visible to any user throughps aux,/proc/<pid>/cmdline, or system audit logs.Affected Files
1.
pkg/stacks/thanos/register_candidate.go:619The
AdminPrivateKeyis directly interpolated into the command string passed tobash -c.2.
pkg/stacks/thanos/shutdown.go:206While using env slice is better, the key is still part of the process environment visible via
/proc/<pid>/environ.Attack Scenario
while true; do ps aux | grep PRIVATE_KEY >> /tmp/keys.txt; sleep 0.1; doneregister-candidateorshutdownoperationsSeverity
CRITICAL — Private key visible in process listing during operation window.
Fix
Replace
fmt.Sprintfcommand strings withexec.Cmd.Envfor environment variable injection:This keeps keys out of the command-line arguments (not visible in
ps aux) while still passing them as environment variables to the child process.References