Fallback pattern-based analysis when SQL parsing fails
(&self, query: &str)
| 451 | |
| 452 | /// Fallback pattern-based analysis when SQL parsing fails |
| 453 | fn fallback_pattern_analysis(&self, query: &str) -> Result<SqlAnalysisResult, PgSqliteError> { |
| 454 | let query_upper = query.to_uppercase(); |
| 455 | |
| 456 | // High-confidence injection patterns |
| 457 | let dangerous_patterns = [ |
| 458 | "'; DROP", |
| 459 | "\"; DROP", |
| 460 | "'; DELETE", |
| 461 | "\"; DELETE", |
| 462 | "' OR '1'='1", |
| 463 | "\" OR \"1\"=\"1\"", |
| 464 | " OR 1=1", |
| 465 | " OR 1 = 1", |
| 466 | "UNION SELECT PASSWORD", |
| 467 | "UNION SELECT * FROM ADMIN", |
| 468 | "UNION SELECT PASSWORD FROM ADMIN", |
| 469 | "EXEC(", |
| 470 | "EXECUTE(", |
| 471 | "XP_CMDSHELL", |
| 472 | "SP_EXECUTESQL", |
| 473 | ]; |
| 474 | |
| 475 | for pattern in &dangerous_patterns { |
| 476 | if query_upper.contains(pattern) { |
| 477 | events::sql_injection_attempt(None, None, query, pattern); |
| 478 | return Err(PgSqliteError::InvalidParameter( |
| 479 | format!("Malicious pattern detected: {}", pattern) |
| 480 | )); |
| 481 | } |
| 482 | } |
| 483 | |
| 484 | // Check for excessive statements |
| 485 | let semicolon_count = query.matches(';').count(); |
| 486 | if semicolon_count > self.max_statements { |
| 487 | events::sql_injection_attempt(None, None, query, "too many statements"); |
| 488 | return Err(PgSqliteError::InvalidParameter( |
| 489 | format!("Too many statements: {}", semicolon_count) |
| 490 | )); |
| 491 | } |
| 492 | |
| 493 | Ok(SqlAnalysisResult::new()) |
| 494 | } |
| 495 | } |
| 496 | |
| 497 | /// Result of SQL injection analysis |
no test coverage detected