diff --git a/.jules/sentinel.md b/.jules/sentinel.md index 1b18e6e83..1a9528255 100644 --- a/.jules/sentinel.md +++ b/.jules/sentinel.md @@ -2,6 +2,11 @@ **Vulnerability:** The manual SVG sanitizer `apps/web/src/lib/sanitize-svg.ts` used an insufficient allowlist/blocklist. It allowed ``, ``, ``, ``, ``, and `` which could lead to mutation XSS (mXSS) and other attack vectors when rendering untrusted Mermaid or Math blocks. **Learning:** Manual DOM tree sanitization is notoriously hard to get right because attackers can hide active elements (e.g. `` tags with `javascript:` payloads) inside grandchild trees (like ``) or use SVG-specific tricks (like ``) which naive list-based cleaners overlook. **Prevention:** Rather than adding heavy third-party dependencies (like DOMPurify) against explicit project instructions, expanding the `BLOCKED` Set to include these structural injection vectors provides a robust, zero-dependency mitigation. Future expansions should verify nested elements carefully. +## 2026-10-22 - [Bypass Command Parsing and Path Traversal fix] +**Vulnerability:** The `validate_read_only` function in `crates/agent/src/tools/workdir_cmd.rs` allowed command parsing bypass (using quoted paths like `cat ".."/".."/etc/passwd`) which facilitated path traversal because the check only matched against the literal block string `../`. +**Learning:** Checking for exact substrings against raw commands is highly fragile against obfuscation, such as Unix-style quotation. +**Prevention:** Validation for string containment (such as blocking `..`) should run against the tokenized and normalized (i.e., lower-case without surrounding quotes) arguments, not the unparsed raw command line. + ## 2023-10-25 - [Fix Masking of Secrets in Environment Variables] **Vulnerability:** The `mask_sensitive_env_key` function in `docker.rs` was not properly masking environment variables that contained sensitive keywords (like `AWS_SECRET_ACCESS_KEY`) because it only checked for exact matches or suffix matches (e.g., ends with `_SECRET`). **Learning:** Only matching for suffixes or exact values can leave secrets exposed when developers prefix or infix the sensitive word in the environment variable name. diff --git a/crates/agent/src/tools/workdir_cmd.rs b/crates/agent/src/tools/workdir_cmd.rs index 932065676..77426cbf8 100644 --- a/crates/agent/src/tools/workdir_cmd.rs +++ b/crates/agent/src/tools/workdir_cmd.rs @@ -35,6 +35,7 @@ fn validate_read_only(bin: &str, parts: &[String]) -> std::result::Result<(), St let l = a.to_ascii_lowercase(); if a.starts_with('/') || a.starts_with('~') + || l.contains("..") || l.contains(".env") || l.contains("secret") || l.contains(".git/") @@ -328,6 +329,7 @@ mod tests { assert!(validate_command("git -c x=y status").is_err()); assert!(validate_command("cat .env").is_err()); assert!(validate_command("cat /etc/passwd").is_err()); + assert!(validate_command("cat \"..\"/\"..\"/etc/passwd").is_err()); assert!(validate_command("git branch -D main").is_err()); }