From aa2c3ba0cc66d4fda8d1c2a70dddc557fcdc4feb Mon Sep 17 00:00:00 2001 From: Mick Grove Date: Sat, 30 Aug 2025 19:40:22 -0700 Subject: [PATCH] Decode Base64 blobs and scan their contents for secrets while skipping short strings for performance. This has a small performance impact and can be disabled with --no-base64 --- src/main.rs | 4 +++- src/matcher.rs | 2 +- src/validation/mongodb.rs | 7 ++----- src/validation/postgres.rs | 27 ++++++++++++++++++++------- tests/int_base64.rs | 2 +- 5 files changed, 27 insertions(+), 15 deletions(-) diff --git a/src/main.rs b/src/main.rs index edb0972..6be95c4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -255,7 +255,9 @@ async fn async_main(args: CommandLineArgs) -> Result<()> { } }, }, - Command::SelfUpdate => anyhow::bail!("SelfUpdate command should not reach this branch"), + Command::SelfUpdate => { + anyhow::bail!("SelfUpdate command should not reach this branch") + } } if let Some(msg) = update_msg { info!("{msg}"); diff --git a/src/matcher.rs b/src/matcher.rs index 6f1531e..1cbb16f 100644 --- a/src/matcher.rs +++ b/src/matcher.rs @@ -430,7 +430,7 @@ impl<'a> Matcher<'a> { } } - if !no_base64 { + if !no_base64 { // If the blob contains standalone Base64 blobs, decode and scan them as well const MAX_B64_DEPTH: usize = 2; // decode at most two levels deep let mut b64_stack: Vec<(DecodedData, usize)> = diff --git a/src/validation/mongodb.rs b/src/validation/mongodb.rs index a899a32..19185b6 100644 --- a/src/validation/mongodb.rs +++ b/src/validation/mongodb.rs @@ -107,10 +107,7 @@ pub async fn validate_mongodb(uri: &str) -> Result<(bool, String)> { // ---- refuse localhost/loopback/UDS outright if uri_targets_localhost(uri) { - return Ok(( - false, - "Refusing to validate localhost/loopback MongoDB URIs.".to_string(), - )); + return Ok((false, "Refusing to validate localhost/loopback MongoDB URIs.".to_string())); } let is_srv = uri.starts_with("mongodb+srv://"); @@ -164,4 +161,4 @@ pub fn generate_mongodb_cache_key(mongodb_uri: &str) -> String { let mut hasher = Sha1::new(); hasher.update(mongodb_uri.as_bytes()); format!("MongoDB:{:x}", hasher.finalize()) -} \ No newline at end of file +} diff --git a/src/validation/postgres.rs b/src/validation/postgres.rs index 71ca608..c262b30 100644 --- a/src/validation/postgres.rs +++ b/src/validation/postgres.rs @@ -6,7 +6,11 @@ use rustls::{client::ClientConfig, RootCertStore}; use rustls_native_certs::{load_native_certs, CertificateResult}; use sha1::{Digest, Sha1}; use tokio::time::{error::Elapsed, timeout}; -use tokio_postgres::{config::{Host, SslMode}, tls::NoTls, Config, Error}; +use tokio_postgres::{ + config::{Host, SslMode}, + tls::NoTls, + Config, Error, +}; use tokio_postgres_rustls::MakeRustlsConnect; use tracing::debug; @@ -59,10 +63,12 @@ fn is_local_tcp_host(s: &str) -> bool { // Direct IPs if let Ok(ip) = host.parse::() { return match ip { - std::net::IpAddr::V4(v4) => - v4.is_loopback() || v4.is_unspecified() || v4.is_link_local(), - std::net::IpAddr::V6(v6) => - v6.is_loopback() || v6.is_unspecified() || v6.is_unicast_link_local(), + std::net::IpAddr::V4(v4) => { + v4.is_loopback() || v4.is_unspecified() || v4.is_link_local() + } + std::net::IpAddr::V6(v6) => { + v6.is_loopback() || v6.is_unspecified() || v6.is_unicast_link_local() + } }; } @@ -74,7 +80,6 @@ fn is_local_tcp_host(s: &str) -> bool { || lower.starts_with("localhost6.") } - async fn check_postgres_db_connection( mut cfg: Config, original_mode: SslMode, @@ -201,7 +206,15 @@ mod tests { #[test] fn detects_local_hosts() { - for h in ["localhost", "LOCALHOST", "localhost.localdomain", "localhost6", "127.0.0.1", "[::1]", "::"] { + for h in [ + "localhost", + "LOCALHOST", + "localhost.localdomain", + "localhost6", + "127.0.0.1", + "[::1]", + "::", + ] { assert!(is_local_tcp_host(h), "should treat {h} as local"); } for h in ["db.example.com", "10.0.0.1"] { diff --git a/tests/int_base64.rs b/tests/int_base64.rs index 614ff90..f5d8858 100644 --- a/tests/int_base64.rs +++ b/tests/int_base64.rs @@ -58,4 +58,4 @@ fn skips_base64_when_disabled() -> anyhow::Result<()> { dir.close()?; Ok(()) -} \ No newline at end of file +}