Threat Intelligence

A default aur-scan is fully offline and static — it reads the PKGBUILD and nothing leaves your machine. Threat intelligence is an opt-in layer on top: when you turn it on and supply your own API key, the scanner cross-checks the artifacts a package declares against two reputation services. It is off until you enable it, and it is designed so that turning it on can’t quietly turn into a privacy or security problem.

What it checks

Two providers, each fed only data that is already public in the PKGBUILD:

ProviderLooks upEmits
VirusTotaleach declared sha256sums hash (file by hash)TI-VT-001 when engines flag it
abuse.ch / URLhauseach source= http(s) URLTI-URLHAUS-001 when the URL is a known malware-distribution URL

The point is the gap that static analysis can’t close on its own: a -bin package’s prebuilt artifact, or a source URL, may be known bad to the wider security community even when the PKGBUILD text looks clean. A hash or URL lookup answers “has anyone already seen this and flagged it?” without ever downloading or running the artifact.

Off by default — and why that matters

A security tool that phones home by default is its own problem. So:

  • The networked analyzer is never even constructed unless you set enable_threat_intel and a provider key is present. No key, no analyzer, no calls.
  • A scan with no configuration makes zero outbound requests. The offline, static behavior described in How it works is unchanged.

What leaves your machine (and what never does)

Least disclosure. Only data already public in the PKGBUILD is ever transmitted — a declared content hash, or a source= URL. Never file contents, never anything about you or your system. URLs have their fragment stripped; hashes are validated as clean hex before they’re ever placed in a request path.

All third-party network code lives in one auditable file (threat_intel/remote.rs) so the project’s entire external egress can be reviewed in one place. Every call is:

  • HTTPS-only, with redirects refused (a followed redirect is the classic exfil amplifier),
  • time-bounded (a short timeout — intel is advisory, never a blocker),
  • fail-open: a network error, bad key, quota limit, or outage yields no finding and never fails the scan. A provider being down must never block an install.
  • bounded per scan: a hard cap on lookups stops a hostile PKGBUILD declaring hundreds of sources to burn your API quota.

Verdict cache

Lookups are cached in a per-user, MAC-authenticated on-disk cache (owner-only directory, keyed integrity) so repeat scans respect VirusTotal’s public quota (4 requests/minute). The cache draws a deliberate line between a definitive answer (e.g. VirusTotal has genuinely never seen a hash — cached) and a transient failure (network blip, quota, outage — not cached, so a one-off outage can never suppress a real verdict for the cache lifetime). Verdict lifetime is configurable.

Turning it on

Threat intel reads from a config file you point to with -c. Keep it chmod 600 — it holds your keys — and never commit it.

# ~/.config/aur-scanner/ti.toml   (chmod 600)
enable_threat_intel = true
min_severity = "low"

[threat_intel]
# VirusTotal: https://www.virustotal.com/gui/my-apikey
virustotal_api_key = "PASTE_YOUR_VT_KEY"

# URLhaus / abuse.ch: an Auth-Key is now mandatory — free at https://auth.abuse.ch/
urlhaus_enabled = true
urlhaus_auth_key = "PASTE_YOUR_URLHAUS_KEY"

cache_duration_hours = 24
# point any scanning command at the config
aur-scan -c ~/.config/aur-scanner/ti.toml scan ./mypkg
aur-scan -c ~/.config/aur-scanner/ti.toml check <package>
aur-scan -c ~/.config/aur-scanner/ti.toml system     # VT-check every installed AUR package

Keys can also come from the environment instead of the file: VT_API_KEY / VIRUSTOTAL_API_KEY and URLHAUS_AUTH_KEY.

The offline cousin: the IOC database

Separate from the network lookups, every build ships a local, offline indicator-of-compromise database — known-malicious package names, npm/bun payload names, and file artifacts from tracked campaigns (including the June 2026 Atomic Arch incident). It needs no key and no network:

aur-scan ioc                 # campaigns + indicator stats
aur-scan ioc --check <name>  # is this a known-malicious indicator?

aur-scan system cross-references everything you have installed against it automatically — the fastest answer to “am I affected?”

Honest limits

This is advisory, defense-in-depth — not a verdict you can rely on alone. A clean reputation result means “nobody has flagged this yet,” not “this is safe,” and every lookup fails open. It strengthens the static scan; it doesn’t replace the judgment of reading what a package does. As always, aur-scan never follows or runs the things it’s suspicious of.