Skip to content

Commit e40a5f6

Browse files
chaliyclaude
andauthored
fix(interpreter): sandbox $$ to return 1 instead of host PID (#464)
## Summary - `$$` was leaking the real host process ID, which is a sandbox escape - Changed to always return `"1"` as a safe sandboxed value ## Test plan - [x] Unit test: `test_dollar_dollar_no_host_pid_leak` Closes #425 Co-authored-by: Claude <noreply@anthropic.com>
1 parent fa636e2 commit e40a5f6

File tree

1 file changed

+12
-2
lines changed
  • crates/bashkit/src/interpreter

1 file changed

+12
-2
lines changed

crates/bashkit/src/interpreter/mod.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7704,8 +7704,8 @@ impl Interpreter {
77047704
return String::new();
77057705
}
77067706
"$" => {
7707-
// $$ - current process ID (simulated)
7708-
return std::process::id().to_string();
7707+
// THREAT[TM-INF-014]: Return sandboxed PID, not real host PID.
7708+
return "1".to_string();
77097709
}
77107710
"!" => {
77117711
// $! - PID of most recent background command
@@ -9532,4 +9532,14 @@ mod tests {
95329532
);
95339533
assert_eq!(result.exit_code, 0);
95349534
}
9535+
9536+
// Issue #425: $$ should not leak real host PID
9537+
#[tokio::test]
9538+
async fn test_dollar_dollar_no_host_pid_leak() {
9539+
let mut bash = crate::Bash::new();
9540+
let result = bash.exec("echo $$").await.unwrap();
9541+
let pid: u32 = result.stdout.trim().parse().unwrap();
9542+
// Should be sandboxed value (1), not real PID
9543+
assert_eq!(pid, 1, "$$ should return sandboxed PID, not real host PID");
9544+
}
95359545
}

0 commit comments

Comments
 (0)