From 6852c692c1a31231c80ab81b30f679b47f5d8b4e Mon Sep 17 00:00:00 2001 From: michalsn Date: Thu, 12 Nov 2026 08:49:20 +0100 Subject: [PATCH] docs: warn against passing user input to orderBy() and groupBy() --- docs/database/query_builder.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/docs/database/query_builder.md b/docs/database/query_builder.md index b6ef52c772c0..2eb88a9eedfa 100644 --- a/docs/database/query_builder.md +++ b/docs/database/query_builder.md @@ -729,6 +729,18 @@ $builder->groupBy(['title', 'date']); // Produces: GROUP BY title, date ``` +!!! warning "Warning" + The first parameter is treated as a field name or SQL expression, not as a value. Identifier protection does not prevent SQL injection here, because expressions such as subqueries and function calls are passed through unchanged. Never pass user-supplied data to `groupBy()` without validating it against a list of allowed columns. + + ```php + groupBy($group); + ``` + #### $builder->distinct() Adds the **DISTINCT** keyword to a query: @@ -1020,6 +1032,18 @@ $builder->orderBy('name', 'ASC'); // Produces: ORDER BY `title` DESC, `name` ASC ``` +!!! warning "Warning" + The first parameter is treated as a field name or SQL expression, not as a value. Identifier protection does not prevent SQL injection here, because expressions such as subqueries and function calls are passed through unchanged. Never pass user-supplied data, such as a sort column from the query string, to `orderBy()` without validating it against a list of allowed columns. + + ```php + orderBy($sort, $direction === 'asc' ? 'ASC' : 'DESC'); + ``` + If you choose the `RANDOM` direction option, then the first parameter will be ignored, unless you specify a numeric seed value. ```php