Skip to content

Commit 928e7e9

Browse files
committed
[New] tests: UAT for monitor+root-owned EICAR under prod default; issue #485
[New] tests/uat/05-monitor-mode.bats: @test asserting monitor quarantines a root-owned EICAR in a webuser-owned docroot under scan_ignore_root=1 (explicit re-set overrides Dockerfile bake); regression test closes the coverage hole that let the tier-2 ownership filter regression ship through rc1..rc3; issue #485
1 parent e934c87 commit 928e7e9

3 files changed

Lines changed: 69 additions & 0 deletions

File tree

CHANGELOG

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,11 @@ v2.0.1 | Mar 25 2026:
8181
admits all files regardless of owner so root-owned malware is not silently
8282
dropped; when 1, scan_ignore_root/user/group ownership filters are applied
8383
in monitor mode (opt-in, matches rc1..rc3 behavior); issue #485
84+
[New] tests/uat/05-monitor-mode.bats: UAT scenario asserting monitor quarantines
85+
a root-owned EICAR dropped into a webuser-owned docroot under reporter's
86+
config (scan_ignore_root=1 + monitor_scan_owner_filters=0 default);
87+
regression test closing the coverage hole that let rc1..rc3 ship with the
88+
filter bug; issue #485
8489

8590
-- Changes --
8691

CHANGELOG.RELEASE

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,11 @@ v2.0.1 | Mar 25 2026:
8181
admits all files regardless of owner so root-owned malware is not silently
8282
dropped; when 1, scan_ignore_root/user/group ownership filters are applied
8383
in monitor mode (opt-in, matches rc1..rc3 behavior); issue #485
84+
[New] tests/uat/05-monitor-mode.bats: UAT scenario asserting monitor quarantines
85+
a root-owned EICAR dropped into a webuser-owned docroot under reporter's
86+
config (scan_ignore_root=1 + monitor_scan_owner_filters=0 default);
87+
regression test closing the coverage hole that let rc1..rc3 ship with the
88+
filter bug; issue #485
8489

8590
-- Changes --
8691

@@ -336,3 +341,4 @@ v2.0.1 | Mar 25 2026:
336341
[Fix] RPM/DEB %pre: defensive detection for dir-vs-symlink cpio conflict; install
337342
no longer fails with "rename failed - Is a directory" when prior install.sh
338343
or partial install left real directories at symlink-target paths
344+

tests/uat/05-monitor-mode.bats

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,64 @@ teardown_file() {
9393
[ "$status" -eq 0 ] || [ "$status" -eq 124 ]
9494
}
9595

96+
# bats test_tags=uat,uat:monitor-mode,uat:issue-485,regression
97+
@test "UAT: monitor quarantines root-owned EICAR in webuser docroot under scan_ignore_root=1" {
98+
if ! command -v inotifywait >/dev/null 2>&1; then
99+
skip "inotifywait not available"
100+
fi
101+
102+
# Ensure webuser-like account exists for docroot ownership
103+
if ! id webuser >/dev/null 2>&1; then
104+
useradd -m -s /bin/bash webuser 2>/dev/null || skip "useradd unavailable"
105+
fi
106+
107+
# Mirror reporter's config: scan_ignore_root=1 (override Dockerfile bake)
108+
# + monitor_scan_owner_filters=0 (the new default post-fix; pin explicitly
109+
# for defense against image-cache variance). Together: scan -a would filter
110+
# root-owned, but monitor should NOT under the fix.
111+
uat_lmd_set_config scan_ignore_root 1
112+
uat_lmd_set_config monitor_scan_owner_filters 0
113+
114+
# Create webuser-owned docroot inside the monitored tree
115+
local _docroot="$MONITOR_DIR/webuser-docroot"
116+
mkdir -p "$_docroot"
117+
chown webuser:webuser "$_docroot"
118+
chmod 755 "$_docroot"
119+
120+
# Start monitor
121+
maldet -b -m "$MONITOR_DIR" > /dev/null 2>&1
122+
123+
if ! uat_wait_for_log "$MALDET_LOG" "inotify startup successful" 15; then
124+
skip "Monitor did not start in time (Docker limitation)"
125+
fi
126+
127+
# Drop a root-owned EICAR into the webuser docroot — exact compromise
128+
# shape targeted by issue #485 fix
129+
local _eicar_path="$_docroot/root-payload.php"
130+
# shellcheck disable=SC2016
131+
printf '%s' 'X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*' \
132+
> "$_eicar_path"
133+
# File is root-owned by default
134+
135+
# Wait for monitor cycle to detect + quarantine
136+
if ! uat_wait_for_condition \
137+
"grep -rl 'root-payload.php' '$LMD_INSTALL/sess/' 2>/dev/null" 30; then
138+
skip "Monitor detection did not trigger in time (Docker limitation)"
139+
fi
140+
141+
# Assert hit in session files
142+
run grep -rl "root-payload.php" "$LMD_INSTALL/sess/" 2>/dev/null
143+
assert_success
144+
145+
# Assert quarantine actually occurred (file no longer in docroot)
146+
[ ! -f "$_eicar_path" ] || {
147+
echo "file still present in docroot — quarantine did not fire" >&2
148+
false
149+
}
150+
151+
rm -rf "$_docroot"
152+
}
153+
96154
# bats test_tags=uat,uat:monitor-mode
97155
@test "UAT: monitor stop kills inotify processes" {
98156
if ! command -v inotifywait >/dev/null 2>&1; then

0 commit comments

Comments
 (0)