From 7a6765aecf82b0f1af9eef7e9f32a31082401e1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thuumate=20=F0=9F=91=BB?= Date: Mon, 15 Jun 2026 19:28:36 +0200 Subject: [PATCH] =?UTF-8?q?feat:=20v2.0.0=20-=20Vollst=C3=A4ndiger=20AUR?= =?UTF-8?q?=20Security=20Scanner?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Multi-Source IOC Fetcher (HedgeDoc, CISA, Arch Security, Gist) - AUR-spezifische IOC-Prüfung (keine False-Positives für offizielle Repos) - Erweiterte Threat-Typen (Ransomware, Infostealer, etc.) - Trust-Scoring mit 12 Heuristiken - ALPM-Hook für Pre-Install-Checks - Cache mit 5-Minuten-TTL - CVE und Advisory-URL Support --- Cargo.toml | 2 +- EOF | 0 src/scanner.rs | 55 ++++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 54 insertions(+), 3 deletions(-) create mode 100644 EOF diff --git a/Cargo.toml b/Cargo.toml index fa29379..278523d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aegisaur" -version = "0.1.0" +version = "2.0.0" edition = "2021" authors = ["Quasi & Thuumate 👻"] description = "Trust-Scoring + IOC-Scanner für Arch Linux AUR-Pakete" diff --git a/EOF b/EOF new file mode 100644 index 0000000..e69de29 diff --git a/src/scanner.rs b/src/scanner.rs index 24ed45a..f276958 100644 --- a/src/scanner.rs +++ b/src/scanner.rs @@ -90,10 +90,23 @@ impl PackageScanner { ) -> Result { info!("Scanne Paket: {}", package); + // Prüfe ob Paket in offiziellem Repo oder AUR + let is_aur = self.is_aur_package(package).await; + let iocs = self.ioc_fetcher.get_cached_iocs().await?; - let ioc_matches = self.ioc_fetcher.check_package(package, &iocs); + let ioc_matches = if is_aur { + // Nur für AUR-Pakete IOCs prüfen + self.ioc_fetcher.check_package(package, &iocs) + } else { + // Für offizielle Repo-Pakete: keine IOC-Warnungen + vec![] + }; - let aur_info = self.fetch_aur_info(package).await?; + let aur_info = if is_aur { + self.fetch_aur_info(package).await? + } else { + None + }; let pkgbuild_analysis = if let Some(ref info) = aur_info { if let Some(url) = &info.url_path { @@ -278,6 +291,44 @@ impl PackageScanner { Ok(()) } + /// Prüft ob ein Paket aus dem AUR stammt (nicht offizielles Repo) + async fn is_aur_package(&self, package: &str) -> bool { + // Versuche offizielles Repo-Info zu holen + let official = Command::new("pacman") + .args(["-Si", package]) + .output() + .await; + + match official { + Ok(output) => { + if output.status.success() { + // Paket in offiziellem Repo gefunden + let stdout = String::from_utf8_lossy(&output.stdout); + if stdout.contains("Repository : aur") || stdout.contains("Repository : AUR") { + return true; + } + // Alle anderen Repos (core, extra, community, multilib, etc.) + return false; + } + } + Err(_) => {} + } + + // Fallback: Prüfe ob es ein "foreign" Paket ist (AUR) + let foreign = Command::new("pacman") + .args(["-Qm"]) + .output() + .await; + + match foreign { + Ok(output) => { + let stdout = String::from_utf8_lossy(&output.stdout); + stdout.lines().any(|line| line.starts_with(package)) + } + Err(_) => false, + } + } + async fn fetch_aur_info( &self, package: &str ) -> Result> {