Add validators module
This commit is contained in:
@@ -1,64 +1,35 @@
|
||||
"""Pattern-based dangerous command detection."""
|
||||
|
||||
from typing import List, Optional
|
||||
|
||||
from ..models import Rule, Finding
|
||||
|
||||
|
||||
class PatternValidator:
|
||||
"""Validates shell scripts for dangerous command patterns."""
|
||||
|
||||
DEFAULT_PATTERNS = [
|
||||
Rule(
|
||||
id="DANGER001",
|
||||
name="Dangerous rm -rf with variable",
|
||||
pattern=r"rm\s+-rf?\s+\$\w+",
|
||||
severity="critical",
|
||||
id="DANGER001", name="Dangerous rm -rf with variable",
|
||||
pattern=r"rm\s+-rf?\s+\$\w+", severity="critical",
|
||||
message="Dangerous deletion command with variable: rm -rf with variables can delete unexpected content",
|
||||
suggestion="Avoid using variables with rm -rf. Use absolute paths or verify the variable content first.",
|
||||
),
|
||||
Rule(
|
||||
id="DANGER002",
|
||||
name="Eval with variable",
|
||||
pattern=r"eval\s+\$\w+",
|
||||
severity="critical",
|
||||
id="DANGER002", name="Eval with variable",
|
||||
pattern=r"eval\s+\$\w+", severity="critical",
|
||||
message="eval with variable can lead to command injection",
|
||||
suggestion="Avoid eval with variables. Use safer alternatives like explicit function calls.",
|
||||
),
|
||||
Rule(
|
||||
id="DANGER003",
|
||||
name="Sudo without full path",
|
||||
pattern=r"sudo\s+(rm|cp|mv|chmod|chown|useradd|userdel)\s",
|
||||
severity="critical",
|
||||
id="DANGER003", name="Sudo without full path",
|
||||
pattern=r"sudo\s+(rm|cp|mv|chmod|chown|useradd|userdel)\s", severity="critical",
|
||||
message="sudo command without full path can be exploited",
|
||||
suggestion="Use full path with sudo, e.g., sudo /bin/rm instead of sudo rm",
|
||||
),
|
||||
Rule(
|
||||
id="DANGER004",
|
||||
name="Unrestricted pipe to shell",
|
||||
pattern=r"\|\s*(bash|sh|zsh|fish)\s*(-[a-z]+)?\s*\$\w+",
|
||||
severity="critical",
|
||||
message="Pipe to shell with variable can execute arbitrary commands",
|
||||
suggestion="Avoid piping variables directly to shell interpreters",
|
||||
),
|
||||
Rule(
|
||||
id="DANGER005",
|
||||
name="Backtick command injection",
|
||||
pattern=r"`\$\w+`",
|
||||
severity="critical",
|
||||
message="Backtick substitution with variable can lead to command injection",
|
||||
suggestion="Use $() instead of backticks and validate the variable content",
|
||||
),
|
||||
]
|
||||
|
||||
def __init__(self, custom_rules: Optional[List[Rule]] = None):
|
||||
"""Initialize the pattern validator with optional custom rules."""
|
||||
def __init__(self, custom_rules=None):
|
||||
self.rules = self.DEFAULT_PATTERNS.copy()
|
||||
if custom_rules:
|
||||
self.rules.extend(custom_rules)
|
||||
|
||||
def validate(self, content: str, line_number: Optional[int] = None) -> List[Finding]:
|
||||
"""Validate content for dangerous patterns."""
|
||||
def validate(self, content, line_number=None):
|
||||
findings = []
|
||||
for rule in self.rules:
|
||||
if not rule.enabled:
|
||||
@@ -68,17 +39,3 @@ class PatternValidator:
|
||||
finding = Finding.from_match(rule, match, line_number, content)
|
||||
findings.append(finding)
|
||||
return findings
|
||||
|
||||
def validate_lines(self, lines: List[str]) -> List[Finding]:
|
||||
"""Validate multiple lines, tracking line numbers."""
|
||||
findings = []
|
||||
for line_number, line in enumerate(lines, start=1):
|
||||
line_findings = self.validate(line, line_number)
|
||||
for finding in line_findings:
|
||||
finding.context = line
|
||||
findings.extend(line_findings)
|
||||
return findings
|
||||
|
||||
def check(self, command: str) -> List[Finding]:
|
||||
"""Check a single command for dangerous patterns."""
|
||||
return self.validate(command)
|
||||
|
||||
Reference in New Issue
Block a user