diff options
| author | Mariusz Felisiak <felisiak.mariusz@gmail.com> | 2022-04-01 13:48:47 +0200 |
|---|---|---|
| committer | Mariusz Felisiak <felisiak.mariusz@gmail.com> | 2022-04-11 09:23:12 +0200 |
| commit | 29a6c98b4c13af82064f993f0acc6e8fafa4d3f5 (patch) | |
| tree | c4887e5e3288a71981a457b7f4376ae0c2e45435 /django/db/models/sql/query.py | |
| parent | 2c09e68ec911919360d5f8502cefc312f9e03c5d (diff) | |
[2.2.x] Fixed CVE-2022-28347 -- Protected QuerySet.explain(**options) against SQL injection on PostgreSQL.
Backport of 6723a26e59b0b5429a0c5873941e01a2e1bdbb81 from main.
Diffstat (limited to 'django/db/models/sql/query.py')
| -rw-r--r-- | django/db/models/sql/query.py | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py index 412e817f10..1e823cfe74 100644 --- a/django/db/models/sql/query.py +++ b/django/db/models/sql/query.py @@ -45,6 +45,10 @@ __all__ = ['Query', 'RawQuery'] # SQL comments are forbidden in column aliases. FORBIDDEN_ALIAS_PATTERN = re.compile(r"['`\"\]\[;\s]|--|/\*|\*/") +# Inspired from +# https://www.postgresql.org/docs/current/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS +EXPLAIN_OPTIONS_PATTERN = re.compile(r"[\w\-]+") + def get_field_names_from_opts(opts): return set(chain.from_iterable( @@ -528,6 +532,12 @@ class Query: def explain(self, using, format=None, **options): q = self.clone() + for option_name in options: + if ( + not EXPLAIN_OPTIONS_PATTERN.fullmatch(option_name) or + "--" in option_name + ): + raise ValueError("Invalid option name: '%s'." % option_name) q.explain_query = True q.explain_format = format q.explain_options = options |
