Skip to content

fix(django-spanner): prevent SQL injection in date and time functions - #19040

Open
olavloite wants to merge 1 commit into
mainfrom
spanner-django-use-query-params-for-time-funcs
Open

olavloite wants to merge 1 commit into
mainfrom
spanner-django-use-query-params-for-time-funcs

Conversation

@olavloite

Copy link
Copy Markdown
Contributor

Date and time operations (such as extracting date parts or truncating timestamps) previously formatted timezone names and lookup types directly into the SQL text as raw strings. When an application accepted timezones or date lookups from untrusted user input, this allowed an attacker to break out of quotes and execute arbitrary SQL.

This change eliminates the vulnerability by passing timezones as bound query parameters rather than embedding them in the SQL statement. Date lookup types are also validated against an identifier allowlist before queries are built, following the standard approach used by other Django database engines.

Additionally, fixed-offset timezones are now normalized to the format Cloud Spanner expects, and previously skipped Django SQL injection regression tests have been re-enabled and verified.

@olavloite
olavloite requested a review from a team as a code owner November 10, 2026 16:08

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request addresses SQL injection vulnerabilities in datetime extraction and truncation operations by validating lookup types against an identifier regex and parameterizing timezone offsets rather than interpolating them directly into SQL queries. It also adds comprehensive unit and mock server tests to verify these changes. The feedback points out a bug in the timezone offset formatting logic within _prepare_tzname_delta where 4-digit offsets (e.g., "-0443") are not correctly handled due to an overly restrictive length check, and provides a robust suggestion to fix it.

Date and time operations (such as extracting date parts or truncating
timestamps) previously formatted timezone names and lookup types directly
into the SQL text as raw strings. When an application accepted timezones
or date lookups from untrusted user input, this allowed an attacker to break
out of quotes and execute arbitrary SQL.

This change eliminates the vulnerability by passing timezones as bound query
parameters rather than embedding them in the SQL statement. Date lookup types
are also validated against an identifier allowlist before queries are built,
following the standard approach used by other Django database engines.

Additionally, fixed-offset timezones are now normalized to the format Cloud
Spanner expects, and previously skipped Django SQL injection regression
tests have been re-enabled and verified.
@olavloite
olavloite force-pushed the spanner-django-use-query-params-for-time-funcs branch from b7010af to ed9479d Compare November 10, 2026 16:18
@olavloite

Copy link
Copy Markdown
Contributor Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request addresses SQL injection vulnerabilities in date/time extract and truncation operations by validating lookup types against an identifier regex and parameterizing timezone names instead of interpolating them directly into SQL strings. Additionally, comprehensive unit and mock server tests have been added to verify the validation logic, parameterization, and defense against SQL injection. No review comments were provided, so there is no feedback to address.

This branch has not been deployed

No deployments
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.

1 participant