From a6a35d8806ae1353173dee1d7053a81c5fd33079 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Sun, 29 Mar 2026 12:47:03 +0000 Subject: [PATCH] =?UTF-8?q?=F0=9F=9B=A1=EF=B8=8F=20Sentinel:=20[MEDIUM]=20?= =?UTF-8?q?Fix=20insecure=20file=20permissions=20for=20saved=20output?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🚨 Severity: MEDIUM 💡 Vulnerability: The `maybe_write_text` utility used `std::fs::write` which saves output files (like PSBTs and Offers) with insecure default permissions, making them readable by other users. 🎯 Impact: Local privilege escalation/exposure of sensitive transaction data. 🔧 Fix: Replaced `std::fs::write` with `crate::paths::write_secure_file` to enforce `0o600` permissions. ✅ Verification: Ran `cargo test` and `cargo check`. Added Sentinel journal entry. Co-authored-by: bitcoiner-dev <75873427+bitcoiner-dev@users.noreply.github.com> --- .jules/sentinel.md | 5 +++++ src/utils.rs | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/.jules/sentinel.md b/.jules/sentinel.md index b58d736..986d7ff 100644 --- a/.jules/sentinel.md +++ b/.jules/sentinel.md @@ -2,3 +2,8 @@ **Vulnerability:** The CLI application creates sensitive configuration files and directories (like wallets and snapshot data) using standard `fs::create_dir_all` and `fs::write` in Rust. These standard functions create files/directories using the system's default umask, which typically allows other users on the same Unix-like system to read the sensitive files. **Learning:** This could lead to a local privilege escalation or exposure of sensitive user data if the user runs the CLI on a shared machine. Relying on default system configurations for sensitive files is unsafe. **Prevention:** Always use `std::os::unix::fs::DirBuilderExt` and `std::os::unix::fs::OpenOptionsExt` to explicitly set file permissions (e.g., `0o700` for directories and `0o600` for files) when creating sensitive data on disk. + +## 2024-03-24 - Secure File Writing Regression Prevention +**Vulnerability:** The `maybe_write_text` utility function was using `std::fs::write`, which resulted in sensitive data (like PSBT files and offers) being saved with insecure default file permissions, making them readable by other users on a shared system. +**Learning:** Even generic utility functions used for saving user-requested command outputs must use secure file permissions (`0o600`) if the data they handle (like PSBTs and offers) is sensitive. +**Prevention:** Always use `crate::paths::write_secure_file` instead of `std::fs::write` for all file writing operations that might contain sensitive material in this codebase. diff --git a/src/utils.rs b/src/utils.rs index dd14d17..8e3996f 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -93,7 +93,7 @@ pub(crate) fn best_match<'a>(needle: &str, candidates: &'a [&'a str]) -> Option< pub fn maybe_write_text(path: Option<&str>, text: &str) -> Result<(), crate::error::AppError> { if let Some(path) = path { - std::fs::write(path, text) + crate::paths::write_secure_file(path, text.as_bytes()) .map_err(|e| crate::error::AppError::Io(format!("failed to write to {path}: {e}"))) } else { Ok(())