Real-world attacks

Every code on this page was produced by running aur-scan against a PKGBUILD fixture that reproduces the attack — captured by the project’s audit harness, not written by hand. These are the findings the scanner actually emits today.

The pattern behind all of them: the malicious code was readable in the PKGBUILD or the .install hook before it ran. Nobody was reading. That’s the gap.

Atomic Arch — June 2026

1,500+ orphaned packages were taken over and rigged to pull malicious npm/bun packages (atomic-lockfile, js-digest) from their install hooks, dropping a credential stealer and an eBPF rootkit.

Scanning the atomic-arch fixture fires:

CodeSeverityWhat caught it
ATOMIC-001Criticalreferences the known-malicious atomic-lockfile / js-digest package names
ATOMIC-002Criticala Node/Bun package manager invoked in an .install hook
IOC-001Criticalmatch against the IOC database for this campaign
CHK-005Highall non-VCS sources use SKIP — no integrity check on what’s pulled

“ChaosRAT” fake patches — July 2025

Fake firefox-patch-bin / librewolf-fix-bin packages shipped a remote-access trojan with systemd persistence.

Scanning the chaos-rat fixture fires:

CodeSeverityWhat caught it
PERSIST-001Criticalsystemd service enabled from the install hook
PERSIST-006Criticala unit named to masquerade as a real systemd-*d daemon
INSTALL-001CriticalPython executed inside the .install script
META-001Lowprovides= impersonation of the real package
SRC-007Lowa VCS source not pinned to a commit

Xeactor cryptominers — 2018

Hijacked acroread, balz, and minergate ran a cryptominer, pulling payloads from paste sites and persisting with systemd timers.

Scanning the xeactor-style fixture fires:

CodeSeverityWhat caught it
PASTE-001Criticaldownload from a paste site (ptpb.pw and friends)
PERSIST-002Criticala systemd .timer for periodic re-execution
HIDDEN-001Higha dotfile written into the user’s home
FUNC-001Highnetwork access inside a build/package function

…and the dedicated cryptominer fixture adds CRYPTO-001 (mining-pool stratum+tcp:// connection) and CRYPTO-002 (a known miner binary name).

The other classes it catches

The fixtures cover more than the headline incidents. Real captured findings:

FixtureCodes
curl-bashDLE-001, EXEC-REMOTE, FUNC-001, PRIV-001, SRC-005
reverse-shellSHELL-001, SHELL-002, URL-001, SRC-005
credential-theftCRED-001, CRED-002, BROWSER-001, EXFIL-001, HIDDEN-001, HIDDEN-002, FUNC-001
obfuscatedDEEP-001 (decode-then-execute), OBF-001, OBF-002

A clean package comes back clean: the example-package fixture produces no findings, and git-package produces only the low-severity META-001 / SRC-007 advisories — so --fail-on high exits 0 on both. See the full code list on Detection Codes.

What static analysis won’t catch

Honesty matters for a security tool. aur-scan reads; it does not run. So:

  • Runtime-only behavior. If the payload only acts after install — triggered later, or fetched and executed from a URL the scanner deliberately won’t follow — that’s past the opaque boundary (EXEC-REMOTE). You’re told code runs from <url>; you’re not told what it does.
  • Novel obfuscation. Pattern and decode-and-execute analysis catch a lot, but static analysis can’t promise to catch every newly-obfuscated variant.
  • Typosquatting by name. META-001 catches provides= impersonation, but a package whose name merely resembles a popular one isn’t a static signal.

Treat findings as defense-in-depth, and still read the PKGBUILD on systems that matter. See Security for the full threat model.