Skip to content

(postgres_mcp_server): (SQL rejected with a trailing semi-colon) #469

Closed
@jameselsey

Description

@jameselsey

Describe the bug

The SQL that the MCP server is creating fails it's own risky SQL pattern.

The MCP is creating this query SELECT transaction_date FROM transactions ORDER BY transaction_date ASC LIMIT 1;

However that's being rejected because SUSPICIOUS_PATTERNS contains r'(?i);' which is matching the semi-colon at the end.

Expected Behavior

When the LLM is asked something like How many of X do we have? then I would expect a tool query for select count(*) from x; and to be returned the result

Current Behavior

Check the last log entry here, it shows the query as SELECT transaction_date FROM transactions ORDER BY transaction_date ASC LIMIT 1; and query is rejected because it contains risky SQL pattern

Tool #5: run_query
DEBUG | strands.types.models.model | finished streaming response from model
DEBUG | strands.handlers.tool_handler | tool=<{'toolUseId': 'tooluse_c02N0RifQ9e6x7PUKoUx5Q', 'name': 'run_query', 'input': {'sql': 'SELECT transaction_date FROM transactions ORDER BY transaction_date ASC LIMIT 1;'}}> | invoking
DEBUG | strands.tools.mcp.mcp_agent_tool | invoking MCP tool 'run_query' with tool_use_id=tooluse_c02N0RifQ9e6x7PUKoUx5Q
DEBUG | strands.tools.mcp.mcp_client | [Thread: MainThread, Session: 76704e35-d974-4485-97b9-f8387e1316ce] calling MCP tool 'run_query' synchronously with tool_use_id=tooluse_c02N0RifQ9e6x7PUKoUx5Q

2025-05-30 21:22:54.439 | INFO     | awslabs.postgres_mcp_server.server:run_query:222 - query is rejected because it contains risky SQL pattern, SQL query: SELECT transaction_date FROM transactions ORDER BY transaction_date ASC LIMIT 1;, reasons: [{'type': 'sql', 'message': 'Suspicious pattern in query: SELECT transaction_date FROM transactions ORDER BY transaction_date ASC LIMIT 1;', 'severity': 'high'}]

Reproduction Steps

I'm using Strands to run this, with this MCP configuration:

stdio_mcp_client = MCPClient(lambda: stdio_client(
    StdioServerParameters(
        command="uvx",
        args=[
            "awslabs.postgres-mcp-server@latest",
            "--resource_arn", "my_arn_here",
            "--secret_arn", "my_secrets_arn_here",
            "--database", "mydb",
            "--region", "us-west-2",
            "--readonly", "True"
        ],
        env= {
            "AWS_PROFILE": "myprofile",
            "AWS_REGION": "us-west-2",
            "FASTMCP_LOG_LEVEL": "ERROR"
        },
    )
))

Possible Solution

The rejection is coming from this function:

def check_sql_injection_risk(sql: str) -> list[dict]:
    """Check for potential SQL injection risks in sql query.

    Args:
        sql: query string

    Returns:
        dictionaries containing detected security issue
    """
    issues = []
    for pattern in SUSPICIOUS_PATTERNS:
        if re.search(pattern, sql):
            issues.append(
                {
                    'type': 'sql',
                    'message': f'Suspicious pattern in query: {sql}',
                    'severity': 'high',
                }
            )
            break
    return issues

SUSPICIOUS_PATTERNS contains r'(?i);', , I believe it's matching against the trailing ;. I'm wondering if the semi-colon would be ok providing it's at the end of the SQL statement?

Additional Information/Context

No response

OS

Mac

Server

postgres-mcp-server

Server Version

main/latest

Region experiencing the issue

us-west-2

Other information

No response

Service quota

  • I have reviewed the service quotas for this construct

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions