From a4301e335d3e5f79bc212bb9c411de7dcf6a1c79 Mon Sep 17 00:00:00 2001 From: 7000pctAUTO Date: Thu, 29 Jan 2026 21:22:05 +0000 Subject: [PATCH] Add validators module --- src/validators/security.py | 84 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 src/validators/security.py diff --git a/src/validators/security.py b/src/validators/security.py new file mode 100644 index 0000000..8237499 --- /dev/null +++ b/src/validators/security.py @@ -0,0 +1,84 @@ +"""Security vulnerability scanning module.""" + +from typing import List, Optional + +from ..models import Rule, Finding + + +class SecurityValidator: + """Scans shell scripts for security vulnerabilities.""" + + DEFAULT_PATTERNS = [ + Rule( + id="SECURITY001", + name="Unquoted variable", + pattern=r"(?{}]\s*\$\w+", + severity="high", + message="Shell metacharacters followed by variable can lead to injection", + suggestion="Sanitize variables to remove or escape shell metacharacters", + ), + Rule( + id="SECURITY005", + name="exec with shell variable", + pattern=r"exec\s+.*\$\w+", + severity="high", + message="exec with variable can be exploited", + suggestion="Avoid using variables with exec. Use explicit command paths.", + ), + ] + + def __init__(self, custom_rules: Optional[List[Rule]] = None): + """Initialize the security validator with optional custom rules.""" + 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 security vulnerabilities.""" + findings = [] + for rule in self.rules: + if not rule.enabled: + continue + matches = rule._compiled_pattern.finditer(content) if rule._compiled_pattern else [] + for match in matches: + 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 security vulnerabilities.""" + return self.validate(command)