|
40 | 40 | from django.db.models.sql.datastructures import BaseTable, Empty, Join, MultiJoin |
41 | 41 | from django.db.models.sql.where import AND, OR, ExtraWhere, NothingNode, WhereNode |
42 | 42 | from django.utils.functional import cached_property |
| 43 | +from django.utils.regex_helper import _lazy_re_compile |
43 | 44 | from django.utils.tree import Node |
44 | 45 |
|
45 | 46 | __all__ = ["Query", "RawQuery"] |
46 | 47 |
|
| 48 | +# Quotation marks ('"`[]), whitespace characters, semicolons, or inline |
| 49 | +# SQL comments are forbidden in column aliases. |
| 50 | +FORBIDDEN_ALIAS_PATTERN = _lazy_re_compile(r"['`\"\]\[;\s]|--|/\*|\*/") |
| 51 | + |
47 | 52 |
|
48 | 53 | def get_field_names_from_opts(opts): |
49 | 54 | if opts is None: |
@@ -1091,8 +1096,16 @@ def join_parent_model(self, opts, model, alias, seen): |
1091 | 1096 | alias = seen[int_model] = join_info.joins[-1] |
1092 | 1097 | return alias or seen[None] |
1093 | 1098 |
|
| 1099 | + def check_alias(self, alias): |
| 1100 | + if FORBIDDEN_ALIAS_PATTERN.search(alias): |
| 1101 | + raise ValueError( |
| 1102 | + "Column aliases cannot contain whitespace characters, quotation marks, " |
| 1103 | + "semicolons, or SQL comments." |
| 1104 | + ) |
| 1105 | + |
1094 | 1106 | def add_annotation(self, annotation, alias, is_summary=False, select=True): |
1095 | 1107 | """Add a single annotation expression to the Query.""" |
| 1108 | + self.check_alias(alias) |
1096 | 1109 | annotation = annotation.resolve_expression( |
1097 | 1110 | self, allow_joins=True, reuse=None, summarize=is_summary |
1098 | 1111 | ) |
@@ -2269,6 +2282,7 @@ def add_extra(self, select, select_params, where, params, tables, order_by): |
2269 | 2282 | else: |
2270 | 2283 | param_iter = iter([]) |
2271 | 2284 | for name, entry in select.items(): |
| 2285 | + self.check_alias(name) |
2272 | 2286 | entry = str(entry) |
2273 | 2287 | entry_params = [] |
2274 | 2288 | pos = entry.find("%s") |
|
0 commit comments