Skip to content

Security: Strengthen SQL validation to prevent non-SELECT operations #10

Open
@coderabbitai

Description

@coderabbitai

Problem

The current implementation of query_sql in cratedb_mcp/__main__.py attempts to restrict queries to read-only SELECT statements but uses a weak validation mechanism that can be bypassed.

As demonstrated in test_query_sql_permitted_exploit(), the current validation only checks for the substring 'select' in the query string, which allows SQL injection attacks where the word 'select' is included in the values of an INSERT statement or other data modification queries.

Suggested Solution

Replace the naive string check with a more robust validation using a dedicated SQL parser library like sqlparse:

import sqlparse

def query_sql(query: str) -> Dict[str, Any]:
    # Parse the SQL statement
    parsed = sqlparse.parse(query.strip())
    
    # Check if it's a SELECT statement
    if not parsed or parsed[0].get_type().upper() != 'SELECT':
        raise ValueError('Only SELECT statements are allowed')
    
    # Rest of the function...

Benefits of using sqlparse:

  • Properly handles SQL syntax
  • Correctly identifies statement types
  • More resilient against bypass attempts
  • Handles edge cases like comments and whitespace

Implementation Steps

  1. Add sqlparse as a dependency in pyproject.toml
  2. Modify query_sql to use sqlparse for statement validation
  3. Update tests to verify the improved validation works correctly

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions