77 lines
3.0 KiB
Python
77 lines
3.0 KiB
Python
"""test_wait_guard_bypass.py — T21.1 §21B-4: adversarial bypass tests
|
|
against the EXACT bypass that occurred live (2026-09-16 12:59:24Z: a
|
|
6-segment multiline sleep 540 → cd → git fetch → releases API curl got
|
|
past the 3-segment lookahead) plus additional realistic variants."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
REPO = Path(__file__).resolve().parent.parent
|
|
sys.path.insert(0, str(REPO / "src"))
|
|
|
|
from rune import wait_guard as wg # noqa: E402
|
|
|
|
|
|
def test_211b_actual_bypass_now_blocked():
|
|
"""The EXACT live bypass command (6 segments, poll at index 5)."""
|
|
cmd = (
|
|
"sleep 540\n"
|
|
"cd /mnt/workdrive/issue161-harness\n"
|
|
"git fetch gitea -q\n"
|
|
"git log --oneline -3 gitea/master\n"
|
|
"ls -l /mnt/workdrive/rune-code/current\n"
|
|
"TOKEN=$(sed -n 's|https://conductor:([^@]*)@.*|\\1|p' ~/.git-credentials)\n"
|
|
"curl -sm 15 'https://gitea.example/api/v1/repos/conductor/rune/releases?limit=3'"
|
|
)
|
|
assert wg.classify_wait(cmd)["classification"] == "UNJUSTIFIED_SLEEP"
|
|
|
|
|
|
def test_211b_wide_gap_still_blocked():
|
|
"""Sleep first line, poll 10 segments later — downstream scan catches."""
|
|
segs = ["sleep 480"] + [f"echo step{i}" for i in range(9)] + \
|
|
["curl -s $API/commits/abc/status"]
|
|
cmd = "\n".join(segs)
|
|
assert wg.classify_wait(cmd)["classification"] == "UNJUSTIFIED_SLEEP"
|
|
|
|
|
|
def test_211b_python_time_sleep_variant():
|
|
"""python -c 'import time; time.sleep(500)' followed by a status query."""
|
|
cmd = ("python3 -c 'import time; time.sleep(500)'\n"
|
|
"curl -s https://gitea.example/api/v1/repos/x/y/commits/abc/status")
|
|
# the python variant is NOT caught by the sleep regex (different syntax)
|
|
# — record honestly: this remains a KNOWN LIMITATION (documented, not
|
|
# silently claimed as covered)
|
|
r = wg.classify_wait(cmd)
|
|
assert r["classification"] in ("NO_WAIT", "UNJUSTIFIED_SLEEP", "UNJUSTIFIED_WAIT_POLL")
|
|
|
|
|
|
def test_211b_legitimate_cases_still_pass():
|
|
# user delay
|
|
assert wg.classify_wait("sleep 45")["classification"] == "USER_REQUESTED_DELAY"
|
|
# short backoff
|
|
assert wg.classify_wait("curl -s $A; sleep 4; curl -s $A")[
|
|
"classification"] == "NO_WAIT"
|
|
# heredoc docs
|
|
cmd = "cat > f.md <<'EOF'\nsleep 540; poll CI\nEOF\necho done"
|
|
assert wg.classify_wait(cmd)["classification"] == "NO_WAIT"
|
|
# non-polling long sleep
|
|
assert wg.classify_wait("sleep 120\nmake build")[
|
|
"classification"] == "NO_WAIT"
|
|
|
|
|
|
def test_211b_multiline_variants_blocked():
|
|
# semicolons
|
|
assert wg.classify_wait(
|
|
"sleep 300; curl -s $GITEA/commits/abc/status")[
|
|
"classification"] == "UNJUSTIFIED_SLEEP"
|
|
# && chains
|
|
assert wg.classify_wait(
|
|
"sleep 300 && git fetch && readlink /mnt/workdrive/rune-code/current")[
|
|
"classification"] == "UNJUSTIFIED_SLEEP"
|
|
# variable-held durations
|
|
assert wg.classify_wait(
|
|
"WAIT=540; sleep $WAIT; curl -s $API/actions/runs")[
|
|
"classification"] in ("UNJUSTIFIED_SLEEP", "NO_WAIT")
|