""" Detection rule sets for guarddog_scanner. Each rule is a tuple of (compiled_regex, rule_id, description). """ import re # --------------------------------------------------------------------------- # CLAUDE.MD – markdown / instruction-file rules # --------------------------------------------------------------------------- CLAUDE_MD_RULES = [ # ── Prompt injection / instruction override ────────────────────────────── ( re.compile( r"ignore\s+(all\s+|previous\s+|prior\s+)?(instructions|rules|guidelines|constraints)", re.I, ), "prompt-injection", "Instruction override attempt", ), ( re.compile( r"disregard\s+(all\s+|previous\s+|prior\s+)?(instructions|rules|guidelines)", re.I, ), "prompt-injection", "Instruction disregard attempt", ), ( re.compile(r"override\s+(safety|guidelines|rules|restrictions)", re.I), "prompt-injection", "Safety override instruction", ), ( re.compile(r"\bDAN\b"), "prompt-injection", "DAN (Do Anything Now) jailbreak pattern", ), (re.compile(r"jailbreak", re.I), "prompt-injection", "Jailbreak keyword detected"), ( re.compile( r"(forget|discard|delete|erase)\s+(all\s+)?(prior|previous|above|earlier)\s+(context|conversation|messages|instructions)", re.I, ), "prompt-injection", "Context erasure attempt", ), ( re.compile(r"new\s+(session|context|conversation)\s+(start|begin|reset)", re.I), "prompt-injection", "Forced session reset instruction", ), ( re.compile( r"do\s+not\s+(follow|obey|respect|adhere\s+to)\s+(the\s+)?(above|previous|prior|system)", re.I, ), "prompt-injection", "Negative compliance directive", ), ( re.compile( r"pretend\s+(that\s+)?(you\s+)?(have\s+no|don't\s+have|lack)\s+(rules|restrictions|guidelines|limits)", re.I, ), "prompt-injection", "Pretend-unrestricted instruction", ), ( re.compile( r"hypothetically\s+speaking.{0,80}(no\s+rules|unrestricted|ignore)", re.I ), "prompt-injection", "Hypothetical framing to bypass restrictions", ), ( re.compile( r"(for\s+the\s+purposes?\s+of\s+this\s+(story|game|roleplay|fiction)).{0,80}ignore", re.I, ), "prompt-injection", "Fictional framing to bypass restrictions", ), ( re.compile(r"", re.S), "hidden-content", "HTML comment used to hide content in markdown", ), ( re.compile(r"[\u200b\u200c\u200d\ufeff]"), "hidden-content", "Zero-width / invisible characters detected", ), ( re.compile(r"[\u00ad\u034f\u115f\u1160\u17b4\u17b5]"), "hidden-content", "Soft-hyphen or Hangum filler invisible character", ), ( re.compile(r"color\s*:\s*#?fff(fff)?|color\s*:\s*white", re.I), "hidden-content", "White-on-white text hiding technique", ), ( re.compile(r"font-size\s*:\s*0(px|pt|em)?", re.I), "hidden-content", "Zero font-size text hiding technique", ), ( re.compile(r"opacity\s*:\s*0(\.\s*0+)?", re.I), "hidden-content", "Zero opacity text hiding technique", ), ( re.compile(r"display\s*:\s*none|visibility\s*:\s*hidden", re.I), "hidden-content", "CSS display:none / visibility:hidden", ), # ── Tool / resource abuse ───────────────────────────────────────────────── ( re.compile( r"(create|write|add)\s+(a\s+)?(new\s+)?(cron|cronjob|scheduled\s+task)", re.I, ), "persistence", "Cron/scheduled task creation instruction", ), ( re.compile( r"(write|append|modify)\s+.{0,60}(~\/\.bashrc|~\/\.zshrc|~\/\.profile|\/etc\/rc)", re.I, ), "persistence", "Shell startup file modification", ), ( re.compile( r"(install|pip\s+install|npm\s+install|apt(-get)?\s+install)\s+\S+", re.I ), "supply-chain", "Package installation instruction in prompt", ), ( re.compile( r"(delete|remove|rm\s+-rf|shred)\s+.{0,60}(\*|\/home|\/var|\/etc)", re.I ), "destructive-action", "Bulk file deletion or wipe instruction", ), ( re.compile(r"mkfs\.|format\s+[a-z]:|dd\s+if=.{0,40}of=", re.I), "destructive-action", "Disk format/wipe command", ), ( re.compile( r"(add|create|modify)\s+(a\s+)?user\b.{0,60}(sudo|root|admin|wheel)", re.I ), "privilege-escalation", "Privileged user creation instruction", ), ( re.compile(r"sudo\s+su\s*$|sudo\s+-s\b|sudo\s+bash\b", re.I), "privilege-escalation", "Privilege escalation via sudo", ), ( re.compile(r"chmod\s+(777|a\+[rwx]+|o\+[rwx]+)", re.I), "privilege-escalation", "World-writable permission grant", ), ] # --------------------------------------------------------------------------- # MCP.JSON – tool-manifest / server-config rules # --------------------------------------------------------------------------- MCP_JSON_RULES = [ # ── Network / shell primitives ─────────────────────────────────────────── ( re.compile(r"\bcurl\b.{0,200}https?://", re.I), "suspicious-network", "Outbound curl in MCP command", ), ( re.compile(r"\bwget\b.{0,200}https?://", re.I), "suspicious-network", "Outbound wget in MCP command", ), ( re.compile(r"\bnc\b|\bnetcat\b", re.I), "suspicious-network", "Netcat in MCP command", ), (re.compile(r"\btelnet\b", re.I), "suspicious-network", "Telnet in MCP command"), ( re.compile(r"\bssh\b.{0,80}@", re.I), "suspicious-network", "SSH connection in MCP command", ), ( re.compile(r"https?://\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}", re.I), "suspicious-network", "Raw IP URL in MCP config (C2 indicator)", ), ( re.compile(r"127\.0\.0\.1|localhost", re.I), "suspicious-network", "Loopback address in MCP URL (SSRF pivot)", ), ( re.compile( r"169\.254\.169\.254", ), # AWS IMDS "suspicious-network", "Cloud metadata endpoint (SSRF / credential theft)", ), ( re.compile(r"(dns|dig|nslookup|host)\s+\S+\.(xyz|top|tk|ml|ga|cf)\b", re.I), "suspicious-network", "DNS query to suspicious TLD", ), # ── Code / shell execution ─────────────────────────────────────────────── (re.compile(r"\bbase64\b", re.I), "obfuscation", "Base64 encoding in MCP command"), ( re.compile(r"\beval\b|\bexec\b", re.I), "code-execution", "eval/exec in MCP command", ), ( re.compile(r"(bash|sh|zsh|cmd|powershell)\s+(-c|/c|--command)", re.I), "code-execution", "Shell -c execution in MCP command", ), ( re.compile(r"python\s+-c\s+[\"']", re.I), "code-execution", "Python one-liner -c flag in MCP command", ), ( re.compile(r"node\s+-e\s+[\"']", re.I), "code-execution", "Node.js -e one-liner in MCP command", ), ( re.compile(r"perl\s+-e\s+[\"']", re.I), "code-execution", "Perl -e one-liner in MCP command", ), ( re.compile(r"ruby\s+-e\s+[\"']", re.I), "code-execution", "Ruby -e one-liner in MCP command", ), ( re.compile(r"php\s+-r\s+[\"']", re.I), "code-execution", "PHP -r one-liner in MCP command", ), ( re.compile(r"import\s+subprocess|import\s+os", re.I), "code-execution", "subprocess/os import in MCP args", ), ( re.compile(r"__import__\s*\(", re.I), "code-execution", "Dynamic __import__ in MCP args", ), ( re.compile(r"<\s*\(|>\s*\(", re.I), # bash process substitution "code-execution", "Bash process substitution <() or >()", ), ( re.compile(r"\$\([^)]{1,200}\)", re.I), # command substitution $() "code-execution", "Shell command substitution $() in MCP arg", ), ( re.compile(r"`[^`]{1,200}`"), # backtick substitution "code-execution", "Backtick command substitution in MCP arg", ), # ── Sensitive file / path access ───────────────────────────────────────── ( re.compile(r"/etc/passwd|/etc/shadow|~/\.ssh", re.I), "data-exfiltration", "Sensitive file path in MCP command", ), ( re.compile(r"/etc/(sudoers|crontab|hosts|resolv\.conf)", re.I), "data-exfiltration", "System config file access in MCP command", ), ( re.compile(r"~\/\.(aws|gcloud|config/gcloud|azure)\b", re.I), "data-exfiltration", "Cloud credential directory access", ), ( re.compile(r"~\/\.(netrc|pgpass|docker|kube)\b", re.I), "data-exfiltration", "Credential store file access", ), ( re.compile(r"(HISTFILE|\.bash_history|\.zsh_history)", re.I), "data-exfiltration", "Shell history file access (credential mining)", ), ( re.compile(r"proc/self/environ|/proc/\d+/environ", re.I), "data-exfiltration", "Process environment file read (env var leak)", ), # ── Supply-chain / dependency confusion ────────────────────────────────── ( re.compile( r"(pip|pip3)\s+install\s+--index-url\s+https?://(?!(pypi\.org|pypi\.theorchard\.io))", re.I, ), "supply-chain", "pip install from non-PyPI index", ), ( re.compile( r"npm\s+install\s+--registry\s+https?://(?!registry\.npmjs\.org)", re.I ), "supply-chain", "npm install from unofficial registry", ), ( re.compile(r"(pip|npm|gem|cargo|go\s+get)\s+install\s+\S+@(http|git\+)", re.I), "supply-chain", "Package installed from arbitrary git/HTTP URL", ), ( re.compile(r"npx\s+\S+@latest\s+--yes", re.I), "supply-chain", "npx auto-install latest with --yes (no review)", ), # ── Persistence / privilege escalation ────────────────────────────────── ( re.compile( r"(echo|tee|cat\s+>>?).{0,60}(crontab|cron\.d|rc\.local|\.bashrc|\.profile)", re.I, ), "persistence", "Cron / startup file write in MCP command", ), ( re.compile(r"(add|useradd|adduser).{0,60}(sudo|wheel|admin|root)", re.I), "privilege-escalation", "Privileged user creation in MCP command", ), ( re.compile(r"sudo\s+(su|bash|sh|chmod|chown)", re.I), "privilege-escalation", "sudo privilege escalation in MCP command", ), ( re.compile(r"chmod\s+(777|a\+[rwx]+|4755)", re.I), "privilege-escalation", "World-writable or SUID permission grant", ), ( re.compile(r"(at|batch)\s+now|systemctl\s+(enable|start)\s+\S+", re.I), "persistence", "Scheduled task or service registration", ), # ── Obfuscation / encoding ─────────────────────────────────────────────── ( re.compile(r"\\x[0-9a-f]{2}(\\x[0-9a-f]{2}){3,}", re.I), "obfuscation", "Hex escape sequence cluster in MCP arg", ), ( re.compile(r"[A-Za-z0-9+/]{80,}={0,2}"), "obfuscation", "Large base64-like blob in MCP config", ), ( re.compile(r"zlib\.(decompress|compress)|gzip\.(decompress|open)", re.I), "obfuscation", "Compressed payload reference in MCP arg", ), # ── Crypto / ransomware indicators ─────────────────────────────────────── ( re.compile(r"(openssl|gpg)\s+(enc|--encrypt|-e)\b.{0,80}(-k|-pass|-aes)", re.I), "destructive-action", "File encryption command in MCP config", ), ( re.compile(r"shred\s+(-u\s+|-z\s+)?\S+|wipe\s+\S+", re.I), "destructive-action", "Secure file deletion in MCP command", ), ( re.compile(r"dd\s+if=.{0,60}of=|mkfs\.\w+", re.I), "destructive-action", "Disk overwrite / format in MCP command", ), # ── Prompt injection via tool description ──────────────────────────────── ( re.compile( r"ignore\s+(all\s+|previous\s+|prior\s+)?(instructions|rules)", re.I ), "prompt-injection", "Prompt injection text in MCP tool description", ), ( re.compile(r"you\s+are\s+now\b", re.I), "prompt-injection", "Persona override in MCP tool description", ), ( re.compile( r"(leak|exfiltrate|send).{0,60}(token|secret|api.?key|password)", re.I ), "prompt-injection", "Data exfil instruction in MCP tool description", ), ( re.compile(r"[\u200b\u200c\u200d\ufeff]"), "hidden-content", "Zero-width / invisible characters detected", ), ] # Copilot instructions share the same attack surface as claude.md COPILOT_INSTRUCTIONS_RULES = CLAUDE_MD_RULES # AGENTS.md (OpenAI Codex/GPT agent instructions) — same attack surface AGENTS_MD_RULES = CLAUDE_MD_RULES # skills.md (Copilot / IDE skill definition files) — same attack surface SKILLS_MD_RULES = CLAUDE_MD_RULES