FAQ
Short answers to the things people ask most — what a finding means and how to act on it, when the scanner just reports versus when it stops a build, what it does and doesn’t touch on your machine, and where its limits are. If something here is unclear or wrong, open an issue.
Understanding findings
What a finding actually means, and how to act on one.
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.What do the severity levels mean?
Five levels. Critical — a real privilege or code-execution boundary, or a strong malware indicator; stop and look. High — significant risk that usually warrants checking. Medium — worth noting. Low — minor or best-practice. Info — context, not a concern. The level describes how consequential the pattern is, not how likely the package is to be hostile.How do I investigate a specific finding?
Runaur-scan explain <CODE> (for example aur-scan explain PRIV-002) to see what the code means and why it fires, then open the PKGBUILD at the line the finding points to and read what it actually does. The full catalog is aur-scan codes, or browse Detection codes.Can I allowlist or permanently ignore a finding I've already checked?
No — and that’s deliberate. There’s no allowlist, no suppression file, no “trust this package” switch. Two reasons. First, a mechanism like that trains you to dismiss criticals by reflex, which is exactly the habit that lets a real one through. Second, any “ignore this” feature is something an attacker would try to abuse to silence the detection of their own payload. A critical is meant to make you pause once and verify — not to be switched off. When you’ve confirmed a finding is fine (like the browser sandbox above), you proceed with that knowledge; the tool doesn’t need to forget that it saw it.It flagged something I'm certain is a false positive. What now?
Tell us — open an issue on GitHub with the package and the code. We’d rather tighten a rule than have you learn to skim past findings. “Always verify” is the posture, but a genuinely noisy rule is a bug worth fixing.Will it get in my way?
When the scanner just reports versus when it actually stops a build.
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.Something got flagged but I still want it. Can I continue?
At the interactive gate, yes — on a critical it makes you type the wordyes (so it can’t happen by a stray keypress), and on a high it’s a y/N confirm. The pacman hook is stricter: it runs mid-transaction with nothing to ask, so a critical there just aborts — there’s no type-yes override. The point isn’t to take the decision away from you; it’s to make sure a critical gets a deliberate one.Does it slow down my AUR helper?
Barely. It reads text files and walks the dependency tree — no building, no sandboxing, no downloading the actual source tarballs. Where the work goes depends on how you run it:
- Pacman hook — scans the
PKGBUILDyour helper already cloned (in~/.cache/yay,~/.cache/paru/clone, etc.), so it does no fetching of its own. This is the cheapest path. - Helper wrapper (
aur-scan-wrap paru -S …) — does a quick shallowgit cloneof each package’s AUR repo to scan it before handing off to your helper, which then fetches and builds its own copy. That pre-scan is a separate clone (and is advisory, since the helper re-fetches). Useaur-scan installif you want the exact bytes scanned to be the bytes built. - Standalone
aur-scan scan <dir>— fully local, no network at all.aur-scan check <pkg>shallow-clones each package in the dependency tree from the AUR, and that cloning is the slowest part.
In every mode it’s reading and pattern-matching shell text, never executing it.
How do I hook it into yay or paru?
See Install. You can add a shell gate that scans before the helper builds, or install the pacman hook.aur-scan install <pkg> also fetches, scans, and builds the same directory — so nothing changes between the check and the build.It said it couldn't scan a package and aborted. Why not just continue?
Because a package it can’t read is a package it can’t vouch for, and letting an un-analyzed build through would defeat the point. That’s the fail-closed rule: when in doubt, stop — don’t wave it past.How it works & what it touches
The static-only invariant, and what does and doesn't leave your machine.
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.What if a package downloads code from somewhere else at build time?
You get told about it, with the URL. It flags that as EXEC-REMOTE and stops there on purpose; it will not go fetch and run that code for you. Chasing the link would just make the scanner the thing that runs the payload.Where do the detection rules come from?
Real attacks, not hypotheticals — the June 2026 Atomic Arch npm/bun campaign, the 2025 ChaosRAT packages, the 2018 Xeactor cryptominer, and the classes of trick they used. Each rule has an ID in one auditable catalog. See Real-world attacks.Coverage & limits
What a clean scan does and doesn't promise.
If it comes back clean, is the package definitely safe?
No tool can promise that, and we won’t. A clean scan means none of the known patterns fired — a strong signal, not a guarantee. Static analysis can’t read intent, and a novel trick can dodge any fixed ruleset. Treat it as one good layer, not the whole wall.What about obfuscated or hidden payloads?
It handles a lot of common evasion — base64/hex blobs, variable indirection (x=curl; $x | sh), case tricks — and treats obfuscation itself as suspicious. But obfuscation is an arms race; assume a determined attacker can hide something a static reader won’t catch, which is exactly why it never runs anything and tells you about remote fetches instead of following them.Can I add my own checks?
Yes, without forking or rebuilding. Drop a few lines of TOML into arules.d folder and your rule joins the catalog. See Custom rules.How do I keep the rules up to date?
Update the package — the built-in rules ship with it. Your ownrules.d files are yours and aren’t touched.Project
Who builds it, the license, and how to report a problem.
Free? Open source?
Both. GPL-3.0, written in Rust. Installaur-scanner from the AUR or build it from source.