Skip to content

fix: prevent SQL injection in SnowflakeSearchTool and NL2SQLTool#4994

Open
devin-ai-integration[bot] wants to merge 2 commits intomainfrom
devin/1774037247-fix-sql-injection
Open

fix: prevent SQL injection in SnowflakeSearchTool and NL2SQLTool#4994
devin-ai-integration[bot] wants to merge 2 commits intomainfrom
devin/1774037247-fix-sql-injection

Conversation

@devin-ai-integration
Copy link
Contributor

Summary

Fixes #4993 — SQL injection vulnerability in SnowflakeSearchTool via database and snowflake_schema parameters, and second-order SQL injection in NL2SQLTool via table_name in _fetch_all_available_columns.

SnowflakeSearchTool (snowflake_search_tool.py):

  • Added pattern=r"^[A-Za-z_][A-Za-z0-9_$]*$" to database and snowflake_schema fields on SnowflakeSearchToolInput (Pydantic schema-level validation)
  • Added _validate_identifier() runtime check in _run() as defense-in-depth
  • Double-quoted identifiers in USE DATABASE / USE SCHEMA SQL statements

NL2SQLTool (nl2sql_tool.py):

  • Added _validate_identifier() to sanitize table_name before f-string interpolation in _fetch_all_available_columns()

Both use the same regex matching Snowflake's unquoted identifier rules: must start with a letter or underscore, followed by alphanumerics, underscores, or $.

Review & Testing Checklist for Human

  • Regex strictness: The pattern ^[A-Za-z_][A-Za-z0-9_$]*$ rejects dot-separated identifiers (e.g. db.schema) and hyphenated names. Verify this is acceptable for standalone database/schema/table name fields — should not be an issue since these are single identifiers, but confirm against real Snowflake usage.
  • Duplicated _validate_identifier: The identical static method exists in both SnowflakeSearchTool and NL2SQLTool. Decide if this should be extracted to a shared utility.
  • query parameter remains unsanitized: By design (the tool's purpose is to execute SQL), but confirm this trade-off is acceptable.

Notes

  • The # noqa: S608 on nl2sql_tool.py:57 is preserved — the f-string interpolation remains but is now gated behind validation.
  • The pre-existing test_cleanup_on_deletion test in the Snowflake test file was already failing before this PR (async context manager on threading.Lock) — not related to these changes.

Link to Devin session: https://app.devin.ai/sessions/c92ac82a6bb44a8889173bbdd664acee

- Add identifier validation regex to database and snowflake_schema fields
  in SnowflakeSearchToolInput to reject malicious values at schema level
- Add _validate_identifier() runtime check in SnowflakeSearchTool._run()
  and double-quote identifiers in USE DATABASE/SCHEMA SQL statements
- Add _validate_identifier() to NL2SQLTool to sanitize table_name in
  _fetch_all_available_columns() preventing second-order SQL injection
- Add comprehensive tests for both tools covering injection vectors

Closes #4993

Co-Authored-By: João <joao@crewai.com>
@devin-ai-integration
Copy link
Contributor Author

Prompt hidden (unlisted session)

@devin-ai-integration
Copy link
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

@@ -0,0 +1,72 @@
from unittest.mock import MagicMock, patch
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

SQL injection in SnowflakeSearchTool via database and schema parameters

0 participants