MCPcopy Create free account
hub / github.com/erans/pgsqlite / analyze_query

Method analyze_query

src/security/sql_injection_detector.rs:51–124  ·  view source on GitHub ↗

Analyze SQL query for injection attempts using AST-based detection

(&self, query: &str)

Source from the content-addressed store, hash-verified

49
50 /// Analyze SQL query for injection attempts using AST-based detection
51 pub fn analyze_query(&self, query: &str) -> Result<SqlAnalysisResult, PgSqliteError> {
52 debug!("Analyzing query for SQL injection: {}", query);
53
54 // Basic length check
55 if query.len() > 1_000_000 {
56 return Err(PgSqliteError::InvalidParameter(
57 format!("Query too long: {} bytes", query.len())
58 ));
59 }
60
61 // Try to parse the SQL
62 let dialect = PostgreSqlDialect {};
63 let statements = match Parser::parse_sql(&dialect, query) {
64 Ok(stmts) => stmts,
65 Err(parse_error) => {
66 // If parsing fails, apply basic pattern-based analysis as fallback
67 warn!("SQL parsing failed, falling back to pattern analysis: {}", parse_error);
68 return self.fallback_pattern_analysis(query);
69 }
70 };
71
72 if statements.len() > self.max_statements {
73 events::sql_injection_attempt(None, None, query, "too many statements");
74 return Err(PgSqliteError::InvalidParameter(
75 format!("Too many statements: {} (max: {})", statements.len(), self.max_statements)
76 ));
77 }
78
79 let mut analysis = SqlAnalysisResult::new();
80
81 for (i, statement) in statements.iter().enumerate() {
82 self.analyze_statement(statement, &mut analysis, 0, query)?;
83
84 // Check for dangerous multi-statement combinations
85 if i > 0 && self.is_dangerous_statement(statement) {
86 events::sql_injection_attempt(None, None, query, "dangerous multi-statement");
87 return Err(PgSqliteError::InvalidParameter(
88 "Dangerous multi-statement query detected".to_string()
89 ));
90 }
91 }
92
93 // Analyze the overall structure
94 if analysis.union_count > self.max_unions {
95 events::sql_injection_attempt(None, None, query, "excessive unions");
96 return Err(PgSqliteError::InvalidParameter(
97 format!("Too many UNION operations: {} (max: {})", analysis.union_count, self.max_unions)
98 ));
99 }
100
101 if analysis.max_depth > self.max_depth {
102 events::sql_injection_attempt(None, None, query, "excessive nesting");
103 return Err(PgSqliteError::InvalidParameter(
104 format!("Query nesting too deep: {} (max: {})", analysis.max_depth, self.max_depth)
105 ));
106 }
107
108 // Check for suspicious tautologies

Callers 6

test_legitimate_queriesFunction · 0.45
test_dangerous_functionsFunction · 0.45
validate_sql_securityMethod · 0.45

Calls 5

sql_injection_attemptFunction · 0.85
analyze_statementMethod · 0.80
lenMethod · 0.45

Tested by 5

test_legitimate_queriesFunction · 0.36
test_dangerous_functionsFunction · 0.36