Description
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