From e02266511aff9c9e55b8c7485bc0616afb07c4ad Mon Sep 17 00:00:00 2001 From: Sharang Parnerkar <30073382+mighty840@users.noreply.github.com> Date: Tue, 12 May 2026 11:49:46 +0200 Subject: [PATCH 1/3] fix: add timeouts to scanners, cap semgrep memory, remove syft remote lookups, fix Script error MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Semgrep was running unbounded with --config=auto (downloads all rules) and no memory cap, making it likely to get OOM-killed in resource-constrained Orca containers. Syft had remote license lookups enabled which adds network calls and memory overhead. Neither had timeouts, so a hung process would stall the entire scan indefinitely and silently produce 0 results. - semgrep: add --max-memory 500 --jobs 1 and a 10-minute timeout - syft: remove remote license lookup env vars, add 5-minute timeout - gitleaks: add 5-minute timeout - dashboard: fix Script dangerous_inner_html -> text child (Dioxus 0.7 Script element requires a single text node child, not dangerous_inner_html — was spamming error logs) Co-Authored-By: Claude Sonnet 4.6 --- compliance-agent/src/pipeline/gitleaks.rs | 47 +++++++++++-------- compliance-agent/src/pipeline/sbom/syft.rs | 30 ++++++------ compliance-agent/src/pipeline/semgrep.rs | 33 +++++++++---- .../src/components/app_shell.rs | 2 +- 4 files changed, 68 insertions(+), 44 deletions(-) diff --git a/compliance-agent/src/pipeline/gitleaks.rs b/compliance-agent/src/pipeline/gitleaks.rs index dd1c221..e830f22 100644 --- a/compliance-agent/src/pipeline/gitleaks.rs +++ b/compliance-agent/src/pipeline/gitleaks.rs @@ -19,26 +19,33 @@ impl Scanner for GitleaksScanner { #[tracing::instrument(skip_all)] async fn scan(&self, repo_path: &Path, repo_id: &str) -> Result { - let output = tokio::process::Command::new("gitleaks") - .args([ - "detect", - "--source", - ".", - "--report-format", - "json", - "--report-path", - "/dev/stdout", - "--no-banner", - "--exit-code", - "0", - ]) - .current_dir(repo_path) - .output() - .await - .map_err(|e| CoreError::Scanner { - scanner: "gitleaks".to_string(), - source: Box::new(e), - })?; + let output = tokio::time::timeout( + std::time::Duration::from_secs(300), + tokio::process::Command::new("gitleaks") + .args([ + "detect", + "--source", + ".", + "--report-format", + "json", + "--report-path", + "/dev/stdout", + "--no-banner", + "--exit-code", + "0", + ]) + .current_dir(repo_path) + .output(), + ) + .await + .map_err(|_| CoreError::Scanner { + scanner: "gitleaks".to_string(), + source: "timed out after 5 minutes".into(), + })? + .map_err(|e| CoreError::Scanner { + scanner: "gitleaks".to_string(), + source: Box::new(e), + })?; if output.stdout.is_empty() { return Ok(ScanOutput::default()); diff --git a/compliance-agent/src/pipeline/sbom/syft.rs b/compliance-agent/src/pipeline/sbom/syft.rs index 93b1502..815f397 100644 --- a/compliance-agent/src/pipeline/sbom/syft.rs +++ b/compliance-agent/src/pipeline/sbom/syft.rs @@ -5,20 +5,22 @@ use compliance_core::CoreError; #[tracing::instrument(skip_all, fields(repo_id = %repo_id))] pub(super) async fn run_syft(repo_path: &Path, repo_id: &str) -> Result, CoreError> { - let output = tokio::process::Command::new("syft") - .arg(repo_path) - .args(["-o", "cyclonedx-json"]) - // Enable remote license lookups for all ecosystems - .env("SYFT_GOLANG_SEARCH_REMOTE_LICENSES", "true") - .env("SYFT_JAVASCRIPT_SEARCH_REMOTE_LICENSES", "true") - .env("SYFT_PYTHON_SEARCH_REMOTE_LICENSES", "true") - .env("SYFT_JAVA_USE_NETWORK", "true") - .output() - .await - .map_err(|e| CoreError::Scanner { - scanner: "syft".to_string(), - source: Box::new(e), - })?; + let output = tokio::time::timeout( + std::time::Duration::from_secs(300), + tokio::process::Command::new("syft") + .arg(repo_path) + .args(["-o", "cyclonedx-json"]) + .output(), + ) + .await + .map_err(|_| CoreError::Scanner { + scanner: "syft".to_string(), + source: "timed out after 5 minutes".into(), + })? + .map_err(|e| CoreError::Scanner { + scanner: "syft".to_string(), + source: Box::new(e), + })?; if !output.status.success() { let stderr = String::from_utf8_lossy(&output.stderr); diff --git a/compliance-agent/src/pipeline/semgrep.rs b/compliance-agent/src/pipeline/semgrep.rs index 5151351..7fc0747 100644 --- a/compliance-agent/src/pipeline/semgrep.rs +++ b/compliance-agent/src/pipeline/semgrep.rs @@ -19,15 +19,30 @@ impl Scanner for SemgrepScanner { #[tracing::instrument(skip_all)] async fn scan(&self, repo_path: &Path, repo_id: &str) -> Result { - let output = tokio::process::Command::new("semgrep") - .args(["--config=auto", "--json", "--quiet"]) - .arg(repo_path) - .output() - .await - .map_err(|e| CoreError::Scanner { - scanner: "semgrep".to_string(), - source: Box::new(e), - })?; + let output = tokio::time::timeout( + std::time::Duration::from_secs(600), + tokio::process::Command::new("semgrep") + .args([ + "--config=auto", + "--json", + "--quiet", + "--max-memory", + "500", + "--jobs", + "1", + ]) + .arg(repo_path) + .output(), + ) + .await + .map_err(|_| CoreError::Scanner { + scanner: "semgrep".to_string(), + source: "timed out after 10 minutes".into(), + })? + .map_err(|e| CoreError::Scanner { + scanner: "semgrep".to_string(), + source: Box::new(e), + })?; if !output.status.success() && output.stdout.is_empty() { let stderr = String::from_utf8_lossy(&output.stderr); diff --git a/compliance-dashboard/src/components/app_shell.rs b/compliance-dashboard/src/components/app_shell.rs index 8c4ae2f..b0816cf 100644 --- a/compliance-dashboard/src/components/app_shell.rs +++ b/compliance-dashboard/src/components/app_shell.rs @@ -32,7 +32,7 @@ pub fn AppShell() -> Element { // Not authenticated — redirect to Keycloak login rsx! { document::Script { - dangerous_inner_html: "window.location.href = '/auth';" + "window.location.href = '/auth';" } } } -- 2.52.0 From 9ff3b9305cd751579b30f4d78cab937cca5da76d Mon Sep 17 00:00:00 2001 From: Sharang Parnerkar <30073382+mighty840@users.noreply.github.com> Date: Tue, 12 May 2026 11:58:21 +0200 Subject: [PATCH 2/3] fix: restore syft remote license lookup env vars Co-Authored-By: Claude Sonnet 4.6 --- compliance-agent/src/pipeline/sbom/syft.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/compliance-agent/src/pipeline/sbom/syft.rs b/compliance-agent/src/pipeline/sbom/syft.rs index 815f397..8b686c8 100644 --- a/compliance-agent/src/pipeline/sbom/syft.rs +++ b/compliance-agent/src/pipeline/sbom/syft.rs @@ -10,6 +10,10 @@ pub(super) async fn run_syft(repo_path: &Path, repo_id: &str) -> Result Date: Tue, 12 May 2026 12:47:16 +0200 Subject: [PATCH 3/3] fix: resolve cargo audit failures MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Update rustls-webpki 0.103.10 → 0.103.13 (fixes RUSTSEC-2026-0098, RUSTSEC-2026-0099, RUSTSEC-2026-0104) - Update mongodb 3.5.1 → 3.6.0 (latest compatible 3.x) - Add .cargo/audit.toml ignoring two hickory-proto advisories that cannot be fixed: mongodb 3.x pins hickory-resolver 0.25.x which pins hickory-proto 0.25.x; RUSTSEC-2026-0118 has no upstream fix at all, RUSTSEC-2026-0119 requires hickory-proto >=0.26.1 which mongodb does not yet support. Both are DNS-layer DoS vectors requiring control of the DNS server responding to MongoDB's hostname resolution. Co-Authored-By: Claude Sonnet 4.6 --- .cargo/audit.toml | 10 ++++++++++ Cargo.lock | 12 ++++++------ 2 files changed, 16 insertions(+), 6 deletions(-) create mode 100644 .cargo/audit.toml diff --git a/.cargo/audit.toml b/.cargo/audit.toml new file mode 100644 index 0000000..e183aab --- /dev/null +++ b/.cargo/audit.toml @@ -0,0 +1,10 @@ +[advisories] +ignore = [ + # hickory-proto 0.25.x pulled in transitively via mongodb → hickory-resolver. + # MongoDB 3.x has not yet released with hickory-resolver 0.26.x, so we cannot + # upgrade past this without a mongodb release. Both are DNS-layer DoS vectors + # requiring a MITM/controlled DNS server against MongoDB's hostname resolution — + # not a realistic attack surface here. Revisit when mongodb bumps hickory. + "RUSTSEC-2026-0118", # NSEC3 loop, no fix available upstream + "RUSTSEC-2026-0119", # O(n²) name compression, fixed in hickory-proto >=0.26.1 +] diff --git a/Cargo.lock b/Cargo.lock index 378dada..0714ef6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3524,9 +3524,9 @@ checksum = "224484c5d09285a7b8cb0a0c117e847ebd14cb6e4470ecf68cdb89c503b0edb9" [[package]] name = "mongodb" -version = "3.5.1" +version = "3.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "803dd859e8afa084c255a8effd8000ff86f7c8076a50cd6d8c99e8f3496f75c2" +checksum = "1ef2c933617431ad0246fb5b43c425ebdae18c7f7259c87de0726d93b0e7e91b" dependencies = [ "base64", "bitflags", @@ -3570,9 +3570,9 @@ dependencies = [ [[package]] name = "mongodb-internal-macros" -version = "3.5.1" +version = "3.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a973ef3dd3dbc6f6e65bbdecfd9ec5e781b9e7493b0f369a7c62e35d8e5ae2c8" +checksum = "9e5758dc828eb2d02ec30563cba365609d56ddd833190b192beaee2b475a7bb3" dependencies = [ "macro_magic", "proc-macro2", @@ -4699,9 +4699,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.103.10" +version = "0.103.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df33b2b81ac578cabaf06b89b0631153a3f416b0a886e8a7a1707fb51abbd1ef" +checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e" dependencies = [ "ring", "rustls-pki-types", -- 2.52.0