[pitboss/grind] deferred session-0003 (20260517T044708Z-e058)

This commit is contained in:
pitboss 2026-05-17 01:18:54 -05:00
parent 6698eb96eb
commit 2544e5d9da
7 changed files with 257 additions and 10 deletions

View file

@ -208,9 +208,12 @@ pub fn profile_path(name: &str) -> Option<PathBuf> {
}
let dir = profile_dir()?;
let path = dir.join(format!("{key}.sb"));
if !path.exists() {
std::fs::write(&path, source).ok()?;
}
// Always overwrite on first miss in this process so an upgraded nyx
// binary picks up new profile content even when a previous version
// left a stale `.sb` file under `std::env::temp_dir()`. The in-process
// `PROFILE_PATHS` cache then short-circuits subsequent lookups so the
// write happens at most once per profile per process lifetime.
std::fs::write(&path, source).ok()?;
let mut cache = profile_paths().lock().ok()?;
cache.insert(*key, path.clone());
Some(path)

View file

@ -9,6 +9,13 @@
(version 1)
(allow default)
;; The `/Users` denylist uses regex matches on specific secret-bearing
;; subpaths instead of a blanket `(subpath "/Users")` deny. The blanket
;; form blocks every interpreter cold-start (python3 / node / java) at
;; `_path_importer_cache` because Hombrew / Anaconda / pyenv / nvm all
;; install under `/Users/<user>/...`. Narrowing to a specific secret
;; set keeps the harness loadable while still blocking credential
;; exfiltration via a tainted-argv command.
(deny file-read*
(literal "/etc/passwd")
(literal "/etc/master.passwd")
@ -18,7 +25,21 @@
(literal "/private/etc/master.passwd")
(literal "/private/etc/shadow")
(literal "/private/etc/sudoers")
(subpath "/Users")
(regex #"^/Users/[^/]+/\.ssh(/|$)")
(regex #"^/Users/[^/]+/\.aws(/|$)")
(regex #"^/Users/[^/]+/\.gnupg(/|$)")
(regex #"^/Users/[^/]+/\.netrc$")
(regex #"^/Users/[^/]+/\.docker(/|$)")
(regex #"^/Users/[^/]+/\.kube(/|$)")
(regex #"^/Users/[^/]+/\.config/gh(/|$)")
(regex #"^/Users/[^/]+/\.zsh_history$")
(regex #"^/Users/[^/]+/\.bash_history$")
(regex #"^/Users/[^/]+/Library/Keychains(/|$)")
(regex #"^/Users/[^/]+/Library/Cookies(/|$)")
(regex #"^/Users/[^/]+/Library/Mail(/|$)")
(regex #"^/Users/[^/]+/Library/Application Support/com\.apple\.TCC(/|$)")
(regex #"^/Users/[^/]+/Library/Application Support/Slack(/|$)")
(regex #"^/Users/[^/]+/Library/Application Support/Code/User(/|$)")
(subpath "/var/db")
(subpath "/private/var/db")
(subpath "/Library/Keychains"))

View file

@ -9,6 +9,9 @@
(version 1)
(allow default)
;; The `/Users` denylist uses regex matches on specific secret-bearing
;; subpaths instead of a blanket `(subpath "/Users")` deny. See the
;; matching comment in `cmdi.sb` for the cold-start rationale.
(deny file-read*
(literal "/etc/passwd")
(literal "/etc/master.passwd")
@ -18,5 +21,16 @@
(literal "/private/etc/master.passwd")
(literal "/private/etc/shadow")
(literal "/private/etc/sudoers")
(subpath "/Users")
(regex #"^/Users/[^/]+/\.ssh(/|$)")
(regex #"^/Users/[^/]+/\.aws(/|$)")
(regex #"^/Users/[^/]+/\.gnupg(/|$)")
(regex #"^/Users/[^/]+/\.netrc$")
(regex #"^/Users/[^/]+/\.docker(/|$)")
(regex #"^/Users/[^/]+/\.kube(/|$)")
(regex #"^/Users/[^/]+/\.config/gh(/|$)")
(regex #"^/Users/[^/]+/Library/Keychains(/|$)")
(regex #"^/Users/[^/]+/Library/Cookies(/|$)")
(regex #"^/Users/[^/]+/Library/Mail(/|$)")
(regex #"^/Users/[^/]+/Library/Application Support/com\.apple\.TCC(/|$)")
(regex #"^/Users/[^/]+/Library/Application Support/Slack(/|$)")
(subpath "/Library/Keychains"))

View file

@ -21,6 +21,13 @@
(version 1)
(allow default)
;; The `/Users` denylist uses regex matches on specific secret-bearing
;; subpaths instead of a blanket `(subpath "/Users")` deny. See the
;; matching comment in `cmdi.sb` for the cold-start rationale. The
;; FILE_IO profile is the strictest of the cap profiles so the regex
;; set is wider than the CMDI / SSRF profiles: every credential file
;; under `~` plus per-app secret stores (Slack tokens, VS Code user
;; settings, Mail database) are denied.
(deny file-read*
(literal "/etc/passwd")
(literal "/etc/master.passwd")
@ -30,7 +37,21 @@
(literal "/private/etc/master.passwd")
(literal "/private/etc/shadow")
(literal "/private/etc/sudoers")
(subpath "/Users")
(regex #"^/Users/[^/]+/\.ssh(/|$)")
(regex #"^/Users/[^/]+/\.aws(/|$)")
(regex #"^/Users/[^/]+/\.gnupg(/|$)")
(regex #"^/Users/[^/]+/\.netrc$")
(regex #"^/Users/[^/]+/\.docker(/|$)")
(regex #"^/Users/[^/]+/\.kube(/|$)")
(regex #"^/Users/[^/]+/\.config/gh(/|$)")
(regex #"^/Users/[^/]+/\.zsh_history$")
(regex #"^/Users/[^/]+/\.bash_history$")
(regex #"^/Users/[^/]+/Library/Keychains(/|$)")
(regex #"^/Users/[^/]+/Library/Cookies(/|$)")
(regex #"^/Users/[^/]+/Library/Mail(/|$)")
(regex #"^/Users/[^/]+/Library/Application Support/com\.apple\.TCC(/|$)")
(regex #"^/Users/[^/]+/Library/Application Support/Slack(/|$)")
(regex #"^/Users/[^/]+/Library/Application Support/Code/User(/|$)")
(subpath "/var/db")
(subpath "/private/var/db")
(subpath "/var/log")

View file

@ -9,6 +9,9 @@
(version 1)
(allow default)
;; The `/Users` denylist uses regex matches on specific secret-bearing
;; subpaths instead of a blanket `(subpath "/Users")` deny. See the
;; matching comment in `cmdi.sb` for the cold-start rationale.
(deny file-read*
(literal "/etc/passwd")
(literal "/etc/master.passwd")
@ -18,5 +21,16 @@
(literal "/private/etc/master.passwd")
(literal "/private/etc/shadow")
(literal "/private/etc/sudoers")
(subpath "/Users")
(regex #"^/Users/[^/]+/\.ssh(/|$)")
(regex #"^/Users/[^/]+/\.aws(/|$)")
(regex #"^/Users/[^/]+/\.gnupg(/|$)")
(regex #"^/Users/[^/]+/\.netrc$")
(regex #"^/Users/[^/]+/\.docker(/|$)")
(regex #"^/Users/[^/]+/\.kube(/|$)")
(regex #"^/Users/[^/]+/\.config/gh(/|$)")
(regex #"^/Users/[^/]+/Library/Keychains(/|$)")
(regex #"^/Users/[^/]+/Library/Cookies(/|$)")
(regex #"^/Users/[^/]+/Library/Mail(/|$)")
(regex #"^/Users/[^/]+/Library/Application Support/com\.apple\.TCC(/|$)")
(regex #"^/Users/[^/]+/Library/Application Support/Slack(/|$)")
(subpath "/Library/Keychains"))

View file

@ -30,6 +30,11 @@
;; Standard filesystem-escape denylist — shared shape with the other
;; per-cap profiles. `file://`-scheme entity reads of these paths
;; will fault out before the parser hands the contents back.
;; The `/Users` denylist uses regex matches on specific secret-bearing
;; subpaths instead of a blanket `(subpath "/Users")` deny. See the
;; matching comment in `cmdi.sb` for the cold-start rationale. XXE
;; payloads that resolve `file:///Users/<user>/.ssh/id_rsa` still hit
;; EPERM at parser fetch time.
(deny file-read*
(literal "/etc/passwd")
(literal "/etc/master.passwd")
@ -39,5 +44,16 @@
(literal "/private/etc/master.passwd")
(literal "/private/etc/shadow")
(literal "/private/etc/sudoers")
(subpath "/Users")
(regex #"^/Users/[^/]+/\.ssh(/|$)")
(regex #"^/Users/[^/]+/\.aws(/|$)")
(regex #"^/Users/[^/]+/\.gnupg(/|$)")
(regex #"^/Users/[^/]+/\.netrc$")
(regex #"^/Users/[^/]+/\.docker(/|$)")
(regex #"^/Users/[^/]+/\.kube(/|$)")
(regex #"^/Users/[^/]+/\.config/gh(/|$)")
(regex #"^/Users/[^/]+/Library/Keychains(/|$)")
(regex #"^/Users/[^/]+/Library/Cookies(/|$)")
(regex #"^/Users/[^/]+/Library/Mail(/|$)")
(regex #"^/Users/[^/]+/Library/Application Support/com\.apple\.TCC(/|$)")
(regex #"^/Users/[^/]+/Library/Application Support/Slack(/|$)")
(subpath "/Library/Keychains"))