1. Overview
The AurScan module is a security-oriented monitor and static analyzer for Arch User Repository (AUR) build workflows. Its primary purpose is to detect the creation or modification of PKGBUILD files within known AUR helper build/cache directories (e.g., yay, paru, trizen, pikaur) and to perform a lightweight static security inspection of the detected PKGBUILD content.
AurScan operates entirely in user space and integrates with the UI layer by exposing two callback hooks:
- log callback – receives human-readable operational and diagnostic messages
- PKGBUILD detected callback – invoked when a PKGBUILD is detected or when a PKGBUILD is flagged as suspicious
The module uses GIO directory monitoring (via giomm/glibmm) rather than polling, enabling near-real-time detection with minimal overhead.
2. Platform Gating and Distribution Detection
AurScan is enabled only on Arch-based systems. The detection logic parses /etc/os-release and checks both ID and ID_LIKE for known Arch-family identifiers, including:
archmanjaroendeavourosarco
If the system is not detected as Arch-based, monitoring is disabled and a log message is emitted.
3. Initialization and Callback Injection
The module is initialized via:
void initialize(
std::function<void(const std::string&)> logCallback,
std::function<void(const std::string&)> pkgbuildDetectedCallback)
This function stores both callbacks as module-level function objects:
logFunc– operational logging sinkpkgbuildDetectedFunc– detection notification sink
Initialization emits a localized log message confirming that AurScan is ready.
4. Monitoring Architecture
4.1 Monitor Storage and Lifecycle
All active directory monitors are retained in:
static std::vector<Glib::RefPtr<Gio::FileMonitor>> aurMonitors;
This ensures monitor objects remain alive for the duration of the monitoring session and can be cleanly cancelled during shutdown.
4.2 Recursive Directory Monitoring
AurScan monitors directories recursively using addMonitorRecursively(base). For each directory:
- A
Gio::FileMonitoris created using:WATCH_MOVESSEND_MOVED
- The monitor listens to
signal_changed()and filters relevant events
To reduce noise and avoid monitoring build artifacts, the recursion explicitly skips common non-actionable directories:
.git,.svn,.hgpkg,src
Recursion uses std::filesystem::directory_iterator with skip_permission_denied and wraps traversal in try/catch blocks to prevent crashes due to permission issues or transient filesystem errors.
4.3 Dynamic Root Monitoring (New Package Directories)
Many AUR helpers create package build directories dynamically. AurScan handles this by adding a dedicated “root monitor” with addDynamicRootMonitor(root), which listens for new directories under a helper cache root.
On CREATED or MOVED_IN events, if the new path is a directory, AurScan automatically calls addMonitorRecursively() on that directory to begin recursive monitoring for PKGBUILD creation/modification.
5. Monitored Targets and Startup Flow
Monitoring is started via:
void startMonitoring()
If the system is Arch-based, AurScan monitors common AUR helper directories under the user’s home directory:
~/.cache/yay~/.cache/paru/clone~/.cache/trizen~/.cache/pikaur/build
For each existing target directory, AurScan:
- Installs a dynamic root monitor (
addDynamicRootMonitor) - Installs recursive monitors for existing subdirectories (
addMonitorRecursively)
Successful startup emits an “AurScan started” log message.
6. PKGBUILD Detection Logic
AurScan filters filesystem events to reduce spurious notifications. Only the following event types are considered:
CREATEDMOVED_INCHANGES_DONE_HINT
A file is treated as a PKGBUILD candidate if its path ends with the suffix:
PKGBUILD
When detected, AurScan:
- Emits a log message including the PKGBUILD path
- Invokes
pkgbuildDetectedFunc(path)to notify downstream components
7. Duplicate Event Suppression
GIO monitors may generate multiple change events for a single user action (e.g., editor save patterns). To prevent duplicate detections, AurScan implements a short-lived cache:
recentDetections(unordered_set) stores recently reported paths- Entries are automatically removed after 1 second using
Glib::signal_timeout().connect_once()
If a PKGBUILD path is already present in recentDetections, the detection is ignored.
8. Stop / Shutdown
Monitoring is stopped via:
void stopMonitoring()
Shutdown behavior:
- Calls
cancel()on each monitor (guarded by try/catch) - Clears
aurMonitorsto release resources - Emits a localized log message confirming deactivation
9. Static PKGBUILD Analyzer
9.1 Analysis Entry Point
AurScan includes a content inspection routine:
void scanPKGBUILD(const std::string& path)
The analyzer performs a line-by-line scan and flags potentially dangerous constructs commonly associated with malicious PKGBUILD behavior (e.g., remote code execution, destructive commands, unsafe permissions).
9.2 False-positive Reduction: Dependency Line Skipping
To reduce noise, AurScan ignores lines containing typical dependency and metadata arrays which are not executable logic:
depends=(...),makedepends=(...),optdepends=(...)checkdepends=(...),provides=(...),conflicts=(...)
This prevents flagging harmless strings that often contain URLs or package names.
9.3 Suspicious Pattern Set
The analyzer uses a focused list of substring indicators, each mapped to a localized explanation. Examples include:
- Remote fetch + execution (RCE indicators):
curl|,wget|,| sh,| bash - Dynamic execution:
bash -c,python3 -c - Destructive operations:
rm -rf - Unsafe permissions:
chmod 777,install -m 777 - Privileged misuse:
sudoinside PKGBUILD logic - Suspicious system writes: direct references to
/etc/and/usr/bin - Encoded payload hints:
base64 -d
When a pattern is matched:
- The analyzer logs a warning with the line number
- The matched line is logged verbatim for operator review
9.4 Result Reporting Contract
If any suspicious pattern is found:
- A “threats found” log entry is emitted
- The detection callback is invoked with a sentinel prefix:
INFECTED://<path>
If no issues are detected, AurScan emits a “clean PKGBUILD” log entry.
The INFECTED:// prefix acts as a downstream signaling mechanism, allowing consumers to distinguish between “PKGBUILD detected” and “PKGBUILD flagged as suspicious” without changing the callback signature.
10. Security and Operational Considerations
- User-space scope: monitoring targets are within the user’s cache directories; no system-wide monitoring is performed.
- Signal burst handling: duplicate suppression reduces event storms caused by editor save semantics.
- Pattern-based analysis: static checks are heuristic indicators, not formal proof of maliciousness; operator review is recommended for flagged results.
- Extensibility: additional AUR helpers, directories, and pattern rules can be added without changes to the monitoring architecture.
- Fail-safe behavior: permission errors are contained via exception handling, preventing monitoring crashes.
Overall, AurScan provides a pragmatic monitoring layer for AUR build activity, reducing the risk of unnoticed execution of unsafe PKGBUILD constructs and improving transparency of user-space package build workflows.