Kief Studio · Protect
See what an AUR package runs
before it runs.
An AUR package executes whatever's in its PKGBUILD the second you build it. aur-scan reads that code first — the package and everything it drags in with it — so nothing runs on your machine until you've had a look.
paru -S aur-scanner
stable · GPG-signed# check a package and its whole dependency tree before you build
$ aur-scan check some-package
[AUR] some-package
[repo] glibc
# or scan the exact files, then build those same files
$ aur-scan install some-packageStart hereJump straight to what you need
Install
Pick a channel and add the shell gate. Two minutes.
Get set upHow it works
Fetch → parse → analyze → resolve. And why it never runs the package.
See the pipelineCommands
check, install, scan, system — what each is for.
Output & CI
JSON, SARIF, exit codes, and a fail-closed gate for pipelines.
Wire it upDetection codes
All 118 codes across 13 categories, from the authoritative catalog.
Browse the catalogReal-world attacks
Atomic Arch, ChaosRAT, Xeactor — and the codes that fire on each.
See the casesThreat intelligence
Opt-in VirusTotal / URLhaus checks. Off by default, bring your own key.
Turn it onIs it safe?
The static-only threat model — why pointing it at malware can't bite back.
Read the modelReads the whole tree, not just your package
The package you asked for is rarely the one that got hijacked. It's usually a dependency a few levels down. aur-scan walks the full AUR tree, reads every one, and gives you an SBOM so you can see exactly what you're about to build.
Checks the same files it builds
Plenty of tools scan one copy and let your AUR helper go build a different one. aur-scan install fetches once, checks that directory, and builds that directory. Nothing slips in between the check and the build.
It never runs the package
It treats the PKGBUILD as text. No sourcing it, no makepkg, no following a URL it finds inside. If a package tries to pull code from somewhere else, it tells you — it doesn't go grab it for you.
One list you can read and add to
Every check has an ID and lives in one catalog you can actually audit. Want it to catch something it doesn't? Drop a few lines of TOML in a folder. No rebuild, no fork.
Built from what actually happened
The checks come from real AUR attacks: the 2026 npm/bun payload campaign, the 2025 fake-browser RAT packages, the 2018 cryptominer. Not hypotheticals someone dreamed up.
Fits in a pipeline
JSON, SARIF, a proper exit code, and an SBOM you can keep. If you want a gate in CI, it's a one-liner.
The actual problem
The AUR is great. It’s also wide open. Anyone can take over an abandoned
package, and when you build one, its PKGBUILD runs on your machine with your
permissions — before pacman installs a single file. The official repos
(core, extra, multilib) are signed and reviewed, so this isn’t about
them. It’s about the part of Arch where the code runs first and asks questions
never.
It’s not theoretical. This keeps happening:
| When | What happened | What it did |
|---|---|---|
| Jun 2026 | 1,500+ orphaned packages taken over, set to pull npm/bun payloads (atomic-lockfile, js-digest) | Credential stealer plus an eBPF rootkit, dropped from install hooks |
| Jul 2025 | Fake firefox-patch-bin / librewolf-fix-bin | Remote access trojan with systemd persistence |
| 2018 | Hijacked acroread, balz, minergate | Cryptominer via curl | bash and systemd timers |
Every one of these was readable in the PKGBUILD or the install hook before it ran. Nobody was reading. That’s the whole reason this exists: read it first, read everything it pulls in, and never run any of it to find out.
Questions people actually ask
My browser package (brave, chrome, vivaldi…) reports PRIV-002 SUID as critical. Is it dangerous?
Almost certainly not — but the finding is correct, and it’s worth ten seconds of your attention. Chromium-based browsers ship a small helper (chrome-sandbox) that has to be setuid root: it’s what lets the browser build the sandbox that isolates web content from the rest of your system. So the SUID bit is expected here. PRIV-002 flags it because a setuid-root binary is a real privilege boundary — and that’s true whether the package is honest or not, because planting a setuid backdoor looks exactly the same to a static reader. The right move isn’t to silence it; it’s to confirm the binary being made setuid is the sandbox helper and nothing unexpected. Once you’ve seen that, you’re done. This is the tool working as intended, not a bug.Does a finding mean the package is malicious?
No. It means something in the package is worth a human look. Most findings are legitimate behavior that simply could be abused — a setuid helper, a post-install hook, a build-time download. aur-scan’s job is to surface those moments so you decide with your eyes open. It deliberately doesn’t pretend to know intent it can’t see from static text.Will it block my installs?
Only if you’ve wired it into the build path, and how it reacts depends on which gate. A plainaur-scan check or scan only reports — it sets an exit code but never stops a build. The interactive gate (the AUR-helper integration) holds on a critical until you type yes, asks a y/N before proceeding on a high, and lets medium and below through; with no terminal to answer — a script or CI run — it fails closed and denies both critical and high. The pacman hook runs inside the transaction with nothing to prompt, so it aborts on a critical (or any package it couldn’t read) and prints a warning on a high without blocking.Does it run the package while scanning it?
No. It reads the PKGBUILD and install scripts as text. It never sources them, never runs makepkg to look inside, never follows a URL, never executes anything it downloads. Pointing it at a malicious package is safe.Does it phone home or send my data anywhere?
Not by default. It fetches PKGBUILDs and package metadata from the AUR (aur.archlinux.org) — the same thing your AUR helper already does — and otherwise works entirely on your machine. Its indicator database is bundled locally, not queried over the network. A default scan makes zero other outbound calls; nothing about your packages leaves your system. The one exception is opt-in: threat intelligence (VirusTotal / URLhaus) is off unless you enable it and supply your own key, and even then it only sends data already public in the PKGBUILD — a declared source hash or a source= URL — never file contents or anything about you. Every lookup fails open, and all of that network code lives in one auditable file.Why does the AUR need this when pacman doesn't?
The official repos (core, extra, multilib) are signed and reviewed. The AUR isn’t, and a PKGBUILD runs whatever code it wants the moment you build it, before pacman ever installs a file. So the risky moment is the build, not the install. That’s the gap this fills.Does it check dependencies too, or just the package I named?
The whole tree. The package you ask for is rarely the one that’s been tampered with; it’s usually something a few levels down. It resolves the full AUR dependency tree, reads every package in it, and can hand you a CycloneDX SBOM of the lot.Free? Open source?
Both. GPL-3.0, written in Rust. Installaur-scanner from the AUR or build it from source.Who's behind it
We're Kief Studio — Brian and Amelia Gagne, a husband-and-wife engineering team out of Shrewsbury, Massachusetts. We built this in Rust and put it out under GPL-3.0 because we use the AUR every day and wanted to actually see what we were installing.
We don't sell fear here. Good security is just a side effect of building things the right way. If aur-scan flags something it shouldn't, tell us — and if you want it to catch more, the catalog is yours to extend.
📖 We also wrote a book together, The Crossroads of AI Integration. If the "trust, but verify" thing in this tool sounds like you, it's the same idea applied to putting AI to work without getting burned.