6.4 KiB
6.4 KiB
Rule Patterns Guide
Guide for writing effective prevention rule patterns.
Pattern Basics
Regex Engine
- Language: Go regexp (RE2 syntax)
- Flags:
(?i)for case-insensitive matching - Performance: Patterns pre-compiled and cached
Pattern Structure
(?i)(pattern_component_1|pattern_component_2|...)
Anchoring
| Anchor | Meaning | Example |
|---|---|---|
^ |
Start of string | ^git\s+ - starts with "git " |
$ |
End of string | main$ - ends with "main" |
\b |
Word boundary | \brm\b - matches "rm" not "remove" |
Pattern Categories
1. Command Patterns
Match shell commands and their arguments.
Example: Block rm -rf /
(?i)(rm\s+-[a-z]*rf|rm\s+-[a-z]*f[a-z]*r)
Breakdown:
(?i)- Case insensitiverm\s+-- "rm" followed by whitespace and dash[a-z]*rf- Any flags ending with "rf"[a-z]*f[a-z]*r- Flags with "f" before "r"
2. Content Patterns
Match within file content for secrets and vulnerabilities.
Example: API Key Detection
(?i)(api[_-]?key\s*[:=]\s*["'][^"']{10,})
Breakdown:
api[_-]?key- "apikey", "api_key", or "api-key"\s*[:=]\s*- Colon or equals with optional spaces["']- Quote character[^"']{10,}- 10+ non-quote characters (the value)
3. Path Patterns
Match file paths for protected resources.
Example: Protected Directories
(?i)(?:\.claude/|\.claude$|.*\.md$|docs/)
Breakdown:
(?:...)- Non-capturing group\.claude/- Directory pattern\.claude$- Exact match.*\.md$- File extensiondocs/- Directory prefix
Common Pattern Examples
Dangerous Commands
| Pattern | Blocks |
|---|---|
(?i)rm\s+-[a-z]*rf\s*/ |
rm -rf / |
(?i):\(\)\s*\{\s*:|\:&\s*\}; |
Fork bomb |
(?i)mkfs\.\w+\s+/dev/ |
Filesystem format |
(?i)dd\s+.*of=/dev/[sh] |
Direct disk writes |
(?i)>\s*/etc/ |
Overwriting system files |
Git Operations
| Pattern | Blocks |
|---|---|
git\s+push\s+.*--force |
Force pushes |
git\s+push\s+.*--delete |
Branch deletion |
git\s+.*--hard\s+ |
Hard resets |
git\s+(commit\s+--amend|rebase) |
History rewrites |
Secrets & Credentials
| Pattern | Detects |
|---|---|
(?i)api[_-]?key\s*[:=]\s*["'][^"']{10,} |
API keys |
(?i)secret[_-]?key\s*[:=]\s*["'][^"']{10,} |
Secret keys |
(?i)password\s*[:=]\s*["'][^"']{6,} |
Passwords |
(?i)token\s*[:=]\s*["'][^"']{20,} |
Tokens |
bearer\s+[a-zA-Z0-9]{20,} |
Bearer tokens |
-----BEGIN\s+(RSA\s+)?PRIVATE\s+KEY----- |
Private keys |
Database URIs
| Pattern | Detects |
|---|---|
mongodb(\+srv)?://[^:]+:[^@]+@ |
MongoDB with password |
postgres(ql)?://[^:]+:[^@]+@ |
PostgreSQL with password |
mysql://[^:]+:[^@]+@ |
MySQL with password |
redis://:[^@]+@ |
Redis with password |
Container Security
| Pattern | Detects |
|---|---|
USER\s+root |
Root user in Dockerfile |
chmod\s+777 |
World-writable permissions |
--privileged |
Privileged container |
FROM.*:latest |
Latest tag usage |
Vulnerabilities
| Pattern | Detects |
|---|---|
eval\s*\(.*\$ |
Eval with variables |
exec\s*\(.*\$ |
Exec with variables |
innerHTML\s*= |
XSS via innerHTML |
document\.write\s*\( |
XSS via document.write |
SELECT.*FROM.*\$ |
SQL injection |
Pattern Testing
Manual Testing
Use Go's regex tester or online RE2-compatible testers.
package main
import (
"fmt"
"regexp"
)
func main() {
pattern := `(?i)(rm\s+-[a-z]*rf)`
re := regexp.MustCompile(pattern)
tests := []string{
"rm -rf /",
"rm -rf /home",
"rm -Rf /tmp",
"rm -f -r /var",
}
for _, test := range tests {
matches := re.MatchString(test)
fmt.Printf("%q matches: %v\n", test, matches)
}
}
Validation via MCP
Test patterns using the validation endpoint:
curl -X POST http://localhost:8081/mcp/validate \
-H "Content-Type: application/json" \
-d '{
"tool": "guardrail_validate_bash",
"arguments": {
"command": "rm -rf /tmp/test"
}
}'
Adding Rules to Database
SQL Template
INSERT INTO prevention_rules (
rule_id,
name,
pattern,
message,
severity,
category,
enabled
) VALUES (
'CUST-001',
'Custom Rule Name',
'(?i)pattern_here',
'Human-readable violation message',
'error', -- critical, error, warning, info
'security', -- bash, git, security, general
true
);
Severity Guidelines
| Severity | When to Use | Example |
|---|---|---|
| critical | Immediate security risk, data loss | Private keys, destructive commands |
| error | Policy violation, potential harm | Force push, secrets in code |
| warning | Caution needed, review recommended | Large deletions, debug mode |
| info | Informational, no blocking | Statistics, suggestions |
Category Naming
| Category | Use For |
|---|---|
bash |
Shell commands, system operations |
git |
Git operations, version control |
security |
Secrets, credentials, vulnerabilities |
general |
Cross-cutting concerns, file protections |
file_edit |
File path validation |
content |
Code content analysis |
edit |
Edit operation metadata |
Pattern Reference Table
Real patterns from the 36 active rules:
| Rule | Pattern Type | Pattern (Simplified) |
|---|---|---|
| BASH-001 | Command | rm\s+-[a-z]*rf\s*/ |
| GIT-001 | Git | push.*--force.*main |
| API-001 | Secret | api[_-]?key\s*[:=]\s*["'][^"']{10,} |
| DB-001 | URI | mongodb://[^:]+:[^@]+@ |
| CONT-001 | Dockerfile | USER\s+root |
| CODE-003 | Vulnerability | innerHTML\s*= |
Best Practices
- Test thoroughly - Patterns can have false positives
- Use word boundaries -
\brm\bvs justrm - Account for whitespace -
\s*for optional spaces - Consider case variations - Use
(?i)flag - Limit scope - More specific patterns are safer
- Document intent - Comment what the pattern targets
Related Documentation
| Document | Purpose |
|---|---|
| RULES_INDEX_MAP.md | All active rules reference |
| MCP_TOOLS_REFERENCE.md | Using validation tools |
| AGENT_GUARDRAILS.md | Main guardrails guide |