From 60a232c54afee12cbe8c0d3605861ed1f132e1a9 Mon Sep 17 00:00:00 2001 From: "Claude (bootstrap)" Date: Sun, 31 May 2026 10:07:23 -0700 Subject: [PATCH] scan-symlinks: tighten DANGEROUS prefix list to actual destruction class MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previous version of scan-symlinks.php was a verbatim port of the panel's scanTarballForDangerousSymlinks(), which flagged every symlink whose target sits under /etc, /usr, /bin, /sbin, /lib, /lib64, /var/lib, /var/log, /var/cache, or /var/spool. That's the right posture for the panel's pre-extract scan in DIRECT mode — refuse before extract — but it makes the container REFUSE every cpmove that comes from a real cPanel source server, including totally clean ones. Standard cPanel accounts ship with stock symlinks like: homedir/access-logs -> /usr/local/apache/domlogs/ homedir/var/cpanel/styled/current_style -> /usr/local/cpanel/base/frontend/... homedir/.cpanel/email -> /usr/local/cpanel/... homedir/etc -> /var/cpanel/userhomes//etc Every customer tarball has 5-20 of these. Treating them as DANGEROUS made the container abort with verdict=refused before extract.sh ever ran. Surfaced on darkside import to whp02: scan-symlinks found homedir/access-logs (a textbook cPanel symlink) and the import bombed. The real destruction class — what ALFA TEaM Shell uses, what we saw brick whp02 in May — is symlinks whose target is the exact filesystem root or under one of the genuinely catastrophic system trees that either escape the customer account or clobber boot/config/proc state: / exact root (the classic alfasymlink/root) /etc config tampering, /etc/shadow exfil /root root home dir /boot bootloader / kernel /proc process info / kernel knobs /sys sysfs /dev device nodes Everything else (notably /usr, /var) becomes UNCERTAIN: reported in the JSON output but doesn't refuse the tarball. With --cap-drop=ALL --read-only --network none --user 999, a /usr-targeting symlink in the container's sandbox can at worst dangle on extract; it can't touch the host. Co-Authored-By: Claude Opus 4.7 (1M context) --- scripts/lib/scan-symlinks.php | 42 +++++++++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 4 deletions(-) diff --git a/scripts/lib/scan-symlinks.php b/scripts/lib/scan-symlinks.php index e3b98fd..3d36f68 100644 --- a/scripts/lib/scan-symlinks.php +++ b/scripts/lib/scan-symlinks.php @@ -45,11 +45,45 @@ if (!is_file($tarPath) || !is_readable($tarPath)) { exit(2); } -// Same prefix list as the panel. +// Threat model: an "ALFA TEaM Shell"-style payload links into a path that, +// when a recursive walker follows it (or when something writes through it), +// either ESCAPES the customer's account on the destination server OR +// CLOBBERS critical system state. The classification needs to be tight +// enough to catch those — and loose enough to NOT flag the dozens of +// standard cPanel-internal symlinks every customer tarball contains +// (access-logs -> /usr/local/apache/domlogs/, var/cpanel/styled/... +// -> /usr/local/cpanel/base/frontend/..., mailman, etc.). +// +// Earlier versions of this file used the panel's broader list (everything +// under /etc, /usr, /bin, /sbin, /lib, /lib64, /var/lib, /var/log, +// /var/cache, /var/spool) which made the container REFUSE every cpmove +// from a real cPanel source server — including clean ones. The panel +// could afford to be permissive in UNCERTAIN handling because it never +// actually followed the links (removeDirectory now shell-rm's, not +// recursive PHP walk). The container is supposed to QUARANTINE the truly +// destructive ones and let the rest through. +// +// Real-world dangerous prefixes (escapes/clobbers): +// / exact root — ALFA "alfasymlink/root -> /" +// /etc config tampering, /etc/shadow exfil +// /root root home dir +// /boot bootloader / kernel +// /proc process info / kernel knobs +// /sys sysfs +// /dev device nodes +// +// Notably NOT in the list (cPanel-legitimate, kept as UNCERTAIN): +// /usr/local/apache/... access logs +// /usr/local/cpanel/... UI styling, plugins, mailman +// /var/log/... per-user mail logs +// /bin, /sbin customer "fix shell" symlinks (rare but seen) $dangerousPrefixes = [ - '/etc', '/usr', '/bin', '/sbin', '/lib', '/lib64', - '/boot', '/root', - '/var/lib', '/var/log', '/var/cache', '/var/spool', + '/etc', + '/root', + '/boot', + '/proc', + '/sys', + '/dev', ]; $findings = [];