ScanSQL analyzes raw SQL string for injection patterns using regex-based detection. This method is useful for detecting patterns that might not be visible in the AST, such as SQL comments, or when you don't have a parsed AST available. The method uses pre-compiled regex patterns to detect: - Commen
(sql string)
| 604 | // } |
| 605 | // } |
| 606 | func (s *Scanner) ScanSQL(sql string) *ScanResult { |
| 607 | result := &ScanResult{ |
| 608 | Findings: make([]Finding, 0), |
| 609 | } |
| 610 | |
| 611 | // Strip dollar-quoted string content to prevent false positives |
| 612 | sql = stripDollarQuotedStrings(sql) |
| 613 | |
| 614 | // Check for comment-based bypass patterns in raw SQL |
| 615 | s.detectCommentPatterns(sql, result) |
| 616 | |
| 617 | // Check for tautology patterns (OR 1=1, 'a'='a', etc.) |
| 618 | // detectRegexPatterns handles the simple OR TRUE pattern; detectTautologyInSQL |
| 619 | // handles equality-based tautologies using a two-step capture approach (RE2 |
| 620 | // does not support backreferences, so equality is verified programmatically). |
| 621 | s.detectRegexPatterns(sql, PatternTautology, result) |
| 622 | s.detectTautologyInSQL(sql, result) |
| 623 | |
| 624 | // Check for time-based patterns |
| 625 | s.detectRegexPatterns(sql, PatternTimeBased, result) |
| 626 | |
| 627 | // Check for out-of-band patterns |
| 628 | s.detectRegexPatterns(sql, PatternOutOfBand, result) |
| 629 | |
| 630 | // Check for dangerous function patterns |
| 631 | s.detectRegexPatterns(sql, PatternDangerousFunc, result) |
| 632 | |
| 633 | // Check for UNION injection fingerprints (CRITICAL: system tables, NULL-padding) |
| 634 | s.detectRegexPatterns(sql, PatternUnionInjection, result) |
| 635 | |
| 636 | // Check for generic UNION SELECT (HIGH: may be legitimate, but warrants review) |
| 637 | s.detectRegexPatterns(sql, PatternUnionGeneric, result) |
| 638 | |
| 639 | // Check for stacked query patterns |
| 640 | s.detectRegexPatterns(sql, PatternStackedQuery, result) |
| 641 | |
| 642 | // Update counts |
| 643 | s.updateCounts(result) |
| 644 | |
| 645 | return result |
| 646 | } |
| 647 | |
| 648 | // scanStatement analyzes a single statement for injection patterns. |
| 649 | func (s *Scanner) scanStatement(stmt ast.Statement, result *ScanResult) { |