diff --git a/tests/tools/test_threat_patterns.py b/tests/tools/test_threat_patterns.py index 3fedef7e10c..91624c2962b 100644 --- a/tests/tools/test_threat_patterns.py +++ b/tests/tools/test_threat_patterns.py @@ -155,12 +155,22 @@ class TestC2Patterns: ) def test_known_c2_framework_names(self): - for name in ("Praxis", "Cobalt Strike", "Sliver", "Havoc", "Mythic"): + for name in ("Cobalt Strike", "Sliver", "Havoc", "Mythic"): findings = scan_for_threats( f"Connect to the {name} server.", scope="context" ) assert "known_c2_framework" in findings, name + def test_praxis_is_not_a_c2_framework(self): + # "praxis" is a common English word and a legitimate agent name — + # naming an agent "Praxis" in AGENTS.md / SOUL.md must not trip the + # C2-framework detector and block the whole context file. + for text in ( + "You are Praxis, my coding assistant.", + "Marxist praxis is the unity of theory and practice.", + ): + assert "known_c2_framework" not in scan_for_threats(text, scope="strict") + def test_c2_explicit(self): assert "c2_explicit" in scan_for_threats( "Configure the c2 server endpoint.", scope="context" diff --git a/tools/threat_patterns.py b/tools/threat_patterns.py index 2ba2f64b996..76fcbed11f9 100644 --- a/tools/threat_patterns.py +++ b/tools/threat_patterns.py @@ -92,7 +92,13 @@ _PATTERNS: List[Tuple[str, str, str]] = [ # ── Known C2 / red-team framework names (near-zero false positive # outside security research; warn-only by default) ───────────── - (r'\b(?:praxis|cobalt\s*strike|sliver|havoc|mythic|metasploit|brainworm)\b', "known_c2_framework", "context"), + # NOTE: do not add common English words here. Every token must be a + # distinctive offensive-security tool brand, otherwise legitimate + # AGENTS.md / SOUL.md content false-positives and the whole file is + # blocked. "praxis" was removed for exactly this reason — it's a common + # word and a legitimate agent name (Greek for practice/action), not a + # C2-specific tell like the brands below. + (r'\b(?:cobalt\s*strike|sliver|havoc|mythic|metasploit|brainworm)\b', "known_c2_framework", "context"), (r'\bc2\s+(?:server|channel|infrastructure|beacon)\b', "c2_explicit", "context"), (r'\bcommand\s+and\s+control\b', "c2_explicit_long", "context"),