From e678ec655b1c289760d321f35f062cd0263c957e Mon Sep 17 00:00:00 2001 From: Nikketryhard Date: Sat, 14 Feb 2026 18:47:38 -0600 Subject: [PATCH] =?UTF-8?q?fix:=20standalone=20MITM=20=E2=80=94=20remove?= =?UTF-8?q?=20HTTPS=5FPROXY=20with=20iptables,=20fix=20is=5Fagent=20detect?= =?UTF-8?q?ion?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Only set HTTPS_PROXY/HTTP_PROXY when iptables UID isolation is NOT available. With iptables, double-proxying caused profile picture fetches to fail with 'lookup http' DNS errors. - Fix is_agent detection: handle JSON with spaces after colons ("requestType": "agent" vs "requestType":"agent") - Suppress wrapper-not-installed warning in standalone mode - Show 'iptables (standalone)' in banner instead of 'not installed' --- src/main.rs | 13 ++++++++----- src/mitm/proxy.rs | 6 +++--- src/standalone.rs | 8 ++++++++ 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/main.rs b/src/main.rs index 39376d4..8aa5838 100644 --- a/src/main.rs +++ b/src/main.rs @@ -247,7 +247,7 @@ async fn main() { // ── Step 5: Start serving ───────────────────────────────────────────────── let app = api::router(state.clone()); - print_banner(cli.port, &pid, &https_port, &csrf, &token, &mitm_port_actual); + print_banner(cli.port, &pid, &https_port, &csrf, &token, &mitm_port_actual, is_standalone); info!("Listening on http://{addr}"); axum::serve(listener, app) @@ -295,7 +295,7 @@ async fn shutdown_signal() { } } -fn print_banner(port: u16, pid: &str, https_port: &str, csrf: &str, token: &str, mitm: &Option<(u16, String)>) { +fn print_banner(port: u16, pid: &str, https_port: &str, csrf: &str, token: &str, mitm: &Option<(u16, String)>, is_standalone: bool) { let chrome_major = &*constants::CHROME_MAJOR; let ver = crate::constants::antigravity_version(); @@ -319,8 +319,9 @@ fn print_banner(port: u16, pid: &str, https_port: &str, csrf: &str, token: &str, println!(" \x1b[36m ca cert\x1b[0m {ca_path}"); // Check if wrapper is installed - let wrapper_installed = check_wrapper_installed(); - if wrapper_installed { + if is_standalone { + println!(" \x1b[36m wrapper\x1b[0m \x1b[32miptables (standalone)\x1b[0m"); + } else if check_wrapper_installed() { println!(" \x1b[36m wrapper\x1b[0m \x1b[32minstalled\x1b[0m"); } else { println!(" \x1b[36m wrapper\x1b[0m \x1b[33mnot installed\x1b[0m"); @@ -351,7 +352,9 @@ fn print_banner(port: u16, pid: &str, https_port: &str, csrf: &str, token: &str, // Setup hints if let Some((mitm_port, ca_path)) = mitm { - if !check_wrapper_installed() { + if is_standalone { + // Standalone mode uses iptables UID isolation — no wrapper needed + } else if !check_wrapper_installed() { println!(" \x1b[1;33m[!]\x1b[0m mitm wrapper not installed"); println!(" \x1b[2mrun:\x1b[0m ./scripts/mitm-wrapper.sh install"); println!(" \x1b[2mor:\x1b[0m HTTPS_PROXY=http://127.0.0.1:{mitm_port}"); diff --git a/src/mitm/proxy.rs b/src/mitm/proxy.rs index e497b0c..a6f447f 100644 --- a/src/mitm/proxy.rs +++ b/src/mitm/proxy.rs @@ -551,9 +551,9 @@ async fn handle_http_over_tls( let raw_body = super::modify::dechunk(body_slice); // Only modify "agent" requests, not "checkpoint" (LS internal) - let is_agent = raw_body - .windows(20) - .any(|w| w == b"\"requestType\":\"agent" || w == b"requestType\":\"agent\""); + let body_str = String::from_utf8_lossy(&raw_body); + let is_agent = body_str.contains("\"requestType\":\"agent\"") + || body_str.contains("\"requestType\": \"agent\""); if is_agent { if let Some(modified_body) = super::modify::modify_request(&raw_body) { diff --git a/src/standalone.rs b/src/standalone.rs index 4ebd449..3fcfcb5 100644 --- a/src/standalone.rs +++ b/src/standalone.rs @@ -143,6 +143,14 @@ impl StandaloneLS { env_vars.push(("SSL_CERT_FILE".into(), combined_ca_path)); env_vars.push(("SSL_CERT_DIR".into(), "/dev/null".into())); env_vars.push(("NODE_EXTRA_CA_CERTS".into(), mitm.ca_cert_path.clone())); + // Only set HTTPS_PROXY when iptables UID isolation is NOT available. + // With iptables, all outbound traffic is transparently redirected at the + // kernel level — setting HTTPS_PROXY on top causes double-proxying + // (profile picture fetches, etc. break with "lookup http" errors). + if !has_ls_user() { + env_vars.push(("HTTPS_PROXY".into(), format!("http://{}", mitm.proxy_addr))); + env_vars.push(("HTTP_PROXY".into(), format!("http://{}", mitm.proxy_addr))); + } } // Check if 'antigravity-ls' user exists for UID-scoped iptables isolation