Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions .jules/sentinel.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
## 2024-05-24 - Weak Hashing Algorithm (SHA256 without salt)
**Vulnerability:** The codebase was obfuscating credentials and tokens using SHA-256 without a salt. These hashes were stored and used for state integrity checks and multi-sandbox conflict detection.
**Learning:** Pure string equality checks on hashes (`a === b`) for deterministic validation creates an implicit requirement for saltless, fast algorithms which naturally leads to weak hashing implementations.
**Prevention:** For secure operations, prefer Node.js built-ins (`scryptSync` + `timingSafeEqual`). When deterministic state comparison is necessary, it must not apply to secrets; secrets should always use randomized salts and dedicated verification routines.
## 2025-02-27 - Command Injection in docker pull

**Vulnerability:** In `src/lib/inference/vllm.ts`, the `pullImage` function was susceptible to command injection because the `profile.image` value was directly interpolated into a shell string executed via `runShell`. An attacker who could control `profile.image` could inject arbitrary shell commands.

**Learning:** When invoking external commands like `docker`, one should prefer spawning the command directly with its arguments in an array instead of concatenating them into a shell string.

**Prevention:** Use `run` instead of `runShell` where possible, taking advantage of the argv array parameter. Avoid passing un-sanitized user input into strings executed via the shell.

## 2026-05-29 - [Sandbox SSH Command Injection]
**Vulnerability:** Shell Command Injection via interpolation in `spawnSync('ssh')` when clearing sandbox state directories.
**Learning:** `shellQuote` and shell array expansions can be unreliable when passed through SSH command boundaries, leading to potential RCE if filenames are attacker-controlled.
**Prevention:** Avoid shell string interpolation for dynamic lists. Pass arguments as null-terminated strings via `stdin` to remote `xargs -0` for deterministic, un-interpolated execution.
8 changes: 5 additions & 3 deletions src/lib/state/sandbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1208,10 +1208,12 @@ function restoreStateDirs(

// Remove existing state dirs before extracting so stale files from
// later snapshots don't persist after restoring an earlier one.
const rmCmd = localDirs.map((d) => `rm -rf -- ${shellQuote(`${dir}/${d}`)}`).join(" && ");
_log(`Cleaning target dirs before restore: ${rmCmd}`);
const rmCmd = "xargs -0 rm -rf --";
const rmInput = localDirs.map((d) => `${dir}/${d}`).join("\0");
Comment thread
Hardonian marked this conversation as resolved.
_log(`Cleaning target dirs before restore via xargs null-terminated pipe`);
const rmResult = spawnSync("ssh", [...sshArgs(configFile, sandboxName), rmCmd], {
stdio: ["ignore", "pipe", "pipe"],
input: rmInput,
stdio: ["pipe", "pipe", "pipe"],
timeout: 30000,
});
if (rmResult.status !== 0 || rmResult.error || rmResult.signal) {
Expand Down
Loading