From b31f399df2f190d5112b549337465f29e22b355f Mon Sep 17 00:00:00 2001 From: Nightshift Date: Fri, 10 Apr 2026 20:20:54 +0000 Subject: [PATCH] [nightshift] code-quality: automated improvements --- src/analysis/yara.rs | 19 +++-- src/detectors/capability_base64_stager.rs | 2 +- src/detectors/capability_network.rs | 4 +- src/detectors/mod.rs | 2 +- src/lib.rs | 7 ++ src/main.rs | 4 +- src/malwarebazaar.rs | 1 + src/profile.rs | 6 +- src/scan.rs | 88 +++++++++++------------ src/verdict.rs | 17 ++--- 10 files changed, 77 insertions(+), 73 deletions(-) diff --git a/src/analysis/yara.rs b/src/analysis/yara.rs index 56257f2..a29532b 100644 --- a/src/analysis/yara.rs +++ b/src/analysis/yara.rs @@ -81,20 +81,19 @@ pub fn scan_yara_rulepacks( fn derive_rule_severity(rule: &Rule<'_, '_>, pack: RulepackKind) -> &'static str { for (key, value) in rule.metadata() { - if key.eq_ignore_ascii_case("severity") { - if let MetaValue::String(severity) = value { - if let Some(canonical) = canonicalize_severity(severity) { - return canonical; - } - } + if key.eq_ignore_ascii_case("severity") + && let MetaValue::String(severity) = value + && let Some(canonical) = canonicalize_severity(severity) + { + return canonical; } } for (key, value) in rule.metadata() { - if key.eq_ignore_ascii_case("threat_level") { - if let MetaValue::Integer(level) = value { - return severity_from_threat_level(level); - } + if key.eq_ignore_ascii_case("threat_level") + && let MetaValue::Integer(level) = value + { + return severity_from_threat_level(level); } } diff --git a/src/detectors/capability_base64_stager.rs b/src/detectors/capability_base64_stager.rs index 4c77d53..22b3da9 100644 --- a/src/detectors/capability_base64_stager.rs +++ b/src/detectors/capability_base64_stager.rs @@ -185,7 +185,7 @@ pub fn detect(index: &EvidenceIndex) -> Vec { return Vec::new(); } - extracted_file_paths.extend(base64_samples.into_iter()); + extracted_file_paths.extend(base64_samples); let rationale = format!( "Found long base64-like payload(s) with Base64 decode primitive(s) ({}) and dynamic code loading primitive(s) ({}). Network primitives observed: ({}).", diff --git a/src/detectors/capability_network.rs b/src/detectors/capability_network.rs index 85220a7..65dbdea 100644 --- a/src/detectors/capability_network.rs +++ b/src/detectors/capability_network.rs @@ -71,9 +71,7 @@ pub fn detect(index: &EvidenceIndex) -> Vec { } let urls_look_benign = urls_are_all_benign(&extracted_urls); - let severity = if extracted_urls.is_empty() { - "low" - } else if urls_look_benign { + let severity = if extracted_urls.is_empty() || urls_look_benign { "low" } else { "med" diff --git a/src/detectors/mod.rs b/src/detectors/mod.rs index 1c61480..aeb455a 100644 --- a/src/detectors/mod.rs +++ b/src/detectors/mod.rs @@ -98,7 +98,7 @@ fn dedup_and_sort(values: &mut Vec) { } fn dedup_locations(locations: &mut Vec) { - locations.sort_by(|left, right| location_key(left).cmp(&location_key(right))); + locations.sort_by_key(location_key); locations.dedup_by(|left, right| left == right); } diff --git a/src/lib.rs b/src/lib.rs index 53d57b6..4b03c04 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -16,6 +16,7 @@ pub mod verdict; pub use analysis::ArchiveEntry; +/// Shared application state passed to all Axum handlers. #[derive(Clone)] pub struct AppState { pub uploads_dir: PathBuf, @@ -28,6 +29,7 @@ pub struct AppState { pub ai_config: Option, } +/// Incoming scan request specifying which upload to analyze. #[derive(Debug, Deserialize, Clone)] pub struct ScanRequest { pub upload_id: String, @@ -44,6 +46,7 @@ pub struct AuthorMetadata { pub report_count: Option, } +/// Full scan result returned after analyzing a JAR upload. #[derive(Debug, Serialize, Deserialize, Clone)] pub struct ScanRunResponse { pub scan_id: String, @@ -65,6 +68,7 @@ pub struct ScanRunResponse { pub intake: IntakeResult, } +/// Summary of archive intake (file counts and storage info). #[derive(Debug, Serialize, Deserialize, Clone)] pub struct IntakeResult { pub upload_id: String, @@ -73,6 +77,7 @@ pub struct IntakeResult { pub class_file_count: usize, } +/// Classification verdict produced by AI or heuristic analysis. #[derive(Debug, Serialize, Deserialize, Clone)] pub struct Verdict { pub result: String, @@ -84,6 +89,7 @@ pub struct Verdict { pub capabilities_assessment: BTreeMap, } +/// Aggregated findings from pattern, signature, YARA, and detector analysis. #[derive(Debug, Serialize, Deserialize, Clone)] pub struct StaticFindings { pub matches: Vec, @@ -94,6 +100,7 @@ pub struct StaticFindings { pub analyzed_files: usize, } +/// A single finding from the static analysis pipeline. #[derive(Debug, Serialize, Deserialize, Clone)] pub struct Indicator { pub source: String, diff --git a/src/main.rs b/src/main.rs index 6cf1ed2..832b11c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -306,9 +306,7 @@ fn load_ai_config() -> Option { .filter(|value| !value.is_empty()) .unwrap_or_else(|| "2024-10-21".to_string()); - if deployment.is_none() { - return None; - } + deployment.as_ref()?; Some(AiConfig { endpoint, diff --git a/src/malwarebazaar.rs b/src/malwarebazaar.rs index 53f2e23..bef933d 100644 --- a/src/malwarebazaar.rs +++ b/src/malwarebazaar.rs @@ -7,6 +7,7 @@ use serde_json::Value; const MALWAREBAZAAR_API_URL: &str = "https://mb-api.abuse.ch/api/v1/"; +/// Result of a MalwareBazaar hash lookup against known malware samples. #[derive(Debug, Clone, Serialize, Deserialize)] pub struct MalwareBazaarResult { pub sha256_hash: String, diff --git a/src/profile.rs b/src/profile.rs index 8b7e90f..032519d 100644 --- a/src/profile.rs +++ b/src/profile.rs @@ -225,10 +225,10 @@ fn jar_layer_depth(path: &str) -> usize { path.match_indices("!/").count() } -fn find_shallowest_entry<'a, F>( - entries: &'a [ArchiveEntry], +fn find_shallowest_entry( + entries: &[ArchiveEntry], predicate: F, -) -> Option<&'a ArchiveEntry> +) -> Option<&ArchiveEntry> where F: Fn(&ArchiveEntry) -> bool, { diff --git a/src/scan.rs b/src/scan.rs index 46d3a5f..feb28cf 100644 --- a/src/scan.rs +++ b/src/scan.rs @@ -67,41 +67,41 @@ pub async fn run_scan( None }; - if mb_mode == MalwareBazaarMatchMode::ShortCircuit { - if let Some(known_malware) = malwarebazaar_match.clone() { - let explanation = match known_malware.family.as_deref() { - Some(family) => format!("Known malware detected by hash match: {family}."), - None => "Known malware detected by hash match in MalwareBazaar.".to_string(), - }; + if mb_mode == MalwareBazaarMatchMode::ShortCircuit + && let Some(known_malware) = malwarebazaar_match.clone() + { + let explanation = match known_malware.family.as_deref() { + Some(family) => format!("Known malware detected by hash match: {family}."), + None => "Known malware detected by hash match in MalwareBazaar.".to_string(), + }; - let response = ScanRunResponse { - scan_id: build_scan_id(scan_id_override)?, - sha256: Some(sha256_hash), - verdict: Verdict { - result: "MALICIOUS".to_string(), - confidence: 1.0, - risk_score: 100, - method: "malwarebazaar_hash".to_string(), - explanation, - capabilities_assessment: std::collections::BTreeMap::new(), - }, - malwarebazaar: Some(known_malware), - static_findings: None, - capabilities: None, - yara_hits: None, - metadata: None, - profile: None, - intake: IntakeResult { - upload_id: request.upload_id.clone(), - storage_path: upload_path.to_string_lossy().into_owned(), - file_count: 0, - class_file_count: 0, - }, - }; + let response = ScanRunResponse { + scan_id: build_scan_id(scan_id_override)?, + sha256: Some(sha256_hash), + verdict: Verdict { + result: "MALICIOUS".to_string(), + confidence: 1.0, + risk_score: 100, + method: "malwarebazaar_hash".to_string(), + explanation, + capabilities_assessment: std::collections::BTreeMap::new(), + }, + malwarebazaar: Some(known_malware), + static_findings: None, + capabilities: None, + yara_hits: None, + metadata: None, + profile: None, + intake: IntakeResult { + upload_id: request.upload_id.clone(), + storage_path: upload_path.to_string_lossy().into_owned(), + file_count: 0, + class_file_count: 0, + }, + }; - persist_scan_result(state, &response).await?; - return Ok(response); - } + persist_scan_result(state, &response).await?; + return Ok(response); } let root_label = format!("{}.jar", request.upload_id); @@ -299,17 +299,17 @@ pub async fn run_scan( ), }; - if let Some(reason) = high_confidence_static_reason(&static_findings) { - if ai_verdict.result != "MALICIOUS" { - ai_verdict.result = "MALICIOUS".to_string(); - ai_verdict.confidence = ai_verdict.confidence.max(0.9); - ai_verdict.risk_score = ai_verdict.risk_score.max(90); - ai_verdict.explanation = format!( - "High-confidence static indicator detected ({reason}). {}", - ai_verdict.explanation - ); - method = format!("static_override({method})"); - } + if let Some(reason) = high_confidence_static_reason(&static_findings) + && ai_verdict.result != "MALICIOUS" + { + ai_verdict.result = "MALICIOUS".to_string(); + ai_verdict.confidence = ai_verdict.confidence.max(0.9); + ai_verdict.risk_score = ai_verdict.risk_score.max(90); + ai_verdict.explanation = format!( + "High-confidence static indicator detected ({reason}). {}", + ai_verdict.explanation + ); + method = format!("static_override({method})"); } let response = ScanRunResponse { diff --git a/src/verdict.rs b/src/verdict.rs index 52b7bbd..3cf0bd7 100644 --- a/src/verdict.rs +++ b/src/verdict.rs @@ -11,6 +11,7 @@ use url::Url; use crate::StaticFindings; use crate::profile::CapabilityProfile; +/// Configuration for the Azure OpenAI (or compatible) AI verdict endpoint. #[derive(Debug, Clone)] pub struct AiConfig { pub endpoint: String, @@ -197,10 +198,10 @@ fn collect_extracted_artifacts(static_findings: &StaticFindings) -> ExtractedArt if let Some(items) = indicator.extracted_urls.as_ref() { for raw in items { urls.insert(truncate_string(raw.as_str(), 220)); - if let Ok(parsed) = Url::parse(raw.as_str()) { - if let Some(host) = parsed.host_str() { - domains.insert(host.trim().to_ascii_lowercase()); - } + if let Ok(parsed) = Url::parse(raw.as_str()) + && let Some(host) = parsed.host_str() + { + domains.insert(host.trim().to_ascii_lowercase()); } } } @@ -868,10 +869,10 @@ fn parse_verdict_content(content: &str) -> Result { } let trimmed = content.trim(); - if let Some(stripped) = trim_code_fence(trimmed) { - if let Some(parsed) = decode_verdict_json(stripped) { - return Ok(parsed); - } + if let Some(stripped) = trim_code_fence(trimmed) + && let Some(parsed) = decode_verdict_json(stripped) + { + return Ok(parsed); } if let Some((start, end)) = json_object_span(trimmed) {