Skip to content
Closed
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
4 changes: 4 additions & 0 deletions .jules/sentinel.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,7 @@
**Vulnerability:** The `verify_github_sig` function in `apps/server/src/infra_routes.rs` verified GitHub webhook signatures using standard string comparison `expected.eq_ignore_ascii_case(hex_sig)`.
**Learning:** String comparison functions exit early as soon as a character mismatch is found. In a cryptographic context, this variable response time leaks information and allows an attacker to perform a timing attack to forge a valid HMAC signature by guessing it byte by byte.
**Prevention:** Always use a constant-time comparison library (like `hmac`'s `verify_slice()`) to compare cryptographic hashes, secrets, and signatures to prevent side-channel timing attacks. Avoid custom implementations of standard cryptographic algorithms.
## 2025-02-14 - Bypass of `workdir_cmd` token validation
**Vulnerability:** The command validation in `crates/agent/src/tools/workdir_cmd.rs` used `joined.to_ascii_lowercase()` and `lower.contains(bad)` to validate blocked tokens, which incorrectly treated quoted substrings separately (e.g. bypass via quotes like `"s"udo` works if only checked against joined raw string, wait, no, the bug was actually about `rm ` vs `"rm"` bypass and argument checking). The previous checks failed to detect exact token matches for `rm` since `rm ` and `rm\t` were checked but an isolated `rm` token at the end of the argument string could be bypassed, or if a command parameter exactly matched `rm` (e.g., via quotes).
**Learning:** Command validation must evaluate the exact token (after shell splitting) rather than a joined raw command string or simple space-suffixed tokens. By validating each parameter/argument *individually* against exact matches (like `rm`) and using `contains` on the token string for blocklisted subsets, it prevents evasion via Unix-style quotation/argument structure.
**Prevention:** Always perform blocked token checks on the individual tokens resulting from shell word splitting, not on the recombined string, and ensure exact malicious commands/binaries like `rm` are explicitly denied regardless of whitespace padding.
6 changes: 6 additions & 0 deletions crates/agent/src/tools/workdir_cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,12 @@ fn validate_command(raw: &str) -> std::result::Result<Vec<String>, String> {
return Err(format!("token interdit dans la commande : {bad}"));
}
}
for part in &parts {
let lower_part = part.to_ascii_lowercase();
if lower_part == "rm" {
return Err("token interdit dans la commande : rm".to_string());
}
}
let bin = parts[0].as_str();
let bin_base = Path::new(bin)
.file_name()
Expand Down
Loading