Skip to content
Open
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
9 changes: 9 additions & 0 deletions .jules/sentinel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
## 2024-05-18 - Path Traversal in validate_config
**Vulnerability:** The `validate_config` socket command accepts a raw path from the client and blindly calls `expandingTildeInPath` followed by `lstat` and `Data(contentsOf:)`. This allows any local user connecting to the UNIX socket to read any 1MB file on the filesystem that the daemon has permissions for, by specifying paths like `/etc/passwd`.
**Learning:** `expandingTildeInPath` and `.standardizingPath` do not inherently sandbox paths. The socket command lacked directory boundary enforcement (e.g. restricting to `~/.cacheout/`). While the prompt states this socket shouldn't strictly boundary check against `~/.cacheout/` everywhere, arbitrary file read on privileged daemons is dangerous. But wait, memory says: "While the Cacheout headless daemon uses `~/.cacheout/` as a default directory, the `path` parameter in socket commands (like `validate_config`) is intended to accept fully qualified absolute or tilde-prefixed paths from anywhere on the filesystem. Strictly boundary-checking these paths to `~/.cacheout/` breaks functionality."
**Prevention:** If boundary checking is not allowed, this might not be considered a vulnerability in this specific codebase context.

## 2024-05-18 - Command Injection in toolExists
**Vulnerability:** `toolExists` in `CacheCategory` passes user-defined/category-defined string (`requiresTool`) directly into string interpolation for `/usr/bin/which \(tool)`, running it under `/bin/bash -c`. If `requiresTool` is manipulated, it could lead to command injection.
**Learning:** Avoid using string interpolation in shell wrapper commands.
**Prevention:** Use direct `Process` execution without `/bin/bash -c`, e.g., `/usr/bin/env which`.
18 changes: 16 additions & 2 deletions Sources/Cacheout/Models/CacheCategory.swift
Original file line number Diff line number Diff line change
Expand Up @@ -186,8 +186,22 @@ struct CacheCategory: Identifiable, Hashable {
}

private func toolExists(_ tool: String) -> Bool {
let result = shell("/usr/bin/which \(tool)")
return result != nil && !result!.isEmpty
let process = Process()
process.executableURL = URL(fileURLWithPath: "/usr/bin/env")
process.arguments = ["which", tool]
process.standardOutput = FileHandle.nullDevice
process.standardError = FileHandle.nullDevice
process.environment = [
"PATH": "/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin"
]

do {
try process.run()
process.waitUntilExit()
return process.terminationStatus == 0
} catch {
return false
}
}

private func runProbe(_ command: String) -> String? {
Expand Down