Skip to content

Commit e5a108f

Browse files
samdarkvjikgithub-actions[bot]
authored
Document sort input validation and recommend Sort::only() (#257)
Co-authored-by: Sergei Predvoditelev <sergei@predvoditelev.ru> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
1 parent 5d99caf commit e5a108f

3 files changed

Lines changed: 37 additions & 4 deletions

File tree

‎README.md‎

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -243,8 +243,19 @@ To get a `Sort` instance, you can use either `Sort::only()` or `Sort::any()`. `S
243243
for logical fields that have no configuration. `Sort::any()` uses user-specified logical field name and order directly
244244
for fields that have no configuration.
245245

246-
Either way, you pass a config array that specifies which logical fields should be order-able and, optionally, details on
247-
how these should map to real fields order.
246+
Use `Sort::only()` by default, especially when the order comes from user input. Define the allowed logical fields in
247+
application code:
248+
249+
```php
250+
$sort = Sort::only(['id', 'name'])->withOrderString($userInput);
251+
```
252+
253+
`Sort::any()` does not restrict sorting to the configured fields or validate unknown field names. Before passing
254+
untrusted input to `withOrder()` or `withOrderString()` on a `Sort::any()` instance, validate the field names against
255+
the fields your application allows. Passing unchecked field names to a database-backed reader can lead to SQL injection.
256+
257+
In both modes, the config array defines logical fields and, optionally, how they map to real fields and their order.
258+
Only `Sort::only()` restricts sorting to those configured logical fields.
248259

249260
The current order to apply is specified via `withOrder()` where you supply an array with keys corresponding to logical
250261
field names and values correspond to order (`asc` or `desc`). Alternatively `withOrderString()` can be used. In this case,

‎docs/guide/pt-BR/README.md‎

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -207,8 +207,20 @@ Para obter uma instância `Sort`, você pode usar `Sort::only()` ou `Sort::any()
207207
para campos lógicos que não possuem configuração. `Sort::any()` usa o nome do campo lógico especificado pelo usuário e ordena diretamente
208208
para campos que não possuem configuração.
209209

210-
De qualquer forma, você passa um array de configuração que especifica quais campos lógicos devem ser ordenados e, opcionalmente, detalhes sobre
211-
como eles devem ser mapeados para a ordem real dos campos.
210+
Use `Sort::only()` por padrão, especialmente quando a ordenação vier de dados fornecidos pelo usuário. Defina os campos
211+
lógicos permitidos no código da aplicação:
212+
213+
```php
214+
$sort = Sort::only(['id', 'name'])->withOrderString($userInput);
215+
```
216+
217+
`Sort::any()` não restringe a ordenação aos campos configurados nem valida nomes de campos desconhecidos. Antes de passar
218+
dados não confiáveis para `withOrder()` ou `withOrderString()` em uma instância de `Sort::any()`, valide os nomes dos campos
219+
de acordo com os campos permitidos pela aplicação. Passar nomes de campos sem validação para um leitor que consulta um
220+
banco de dados pode levar à injeção de SQL.
221+
222+
Nos dois modos, o array de configuração define os campos lógicos e, opcionalmente, como eles são mapeados para os campos
223+
reais e sua ordenação. Apenas `Sort::only()` restringe a ordenação aos campos lógicos configurados.
212224

213225
A ordem atual a ser aplicada é especificada via `withOrder()` onde você fornece um array com chaves lógicas correspondentes
214226
aos nomes e valores dos campos correspondem à ordem (`asc` ou `desc`). Alternativamente `withOrderString()` pode ser usado. Nesse caso

‎src/Reader/Sort.php‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@
3636
* - {@see Sort::only()} ignores user-specified order for logical fields that have no configuration.
3737
* - {@see Sort::any()} uses user-specified logical field name and order directly for fields that have no configuration.
3838
*
39+
* Use {@see Sort::only()} by default, especially for user input. With {@see Sort::any()}, validate untrusted field names
40+
* against the fields your application allows before setting the order. Unchecked field names can lead to SQL injection
41+
* when used with a database-backed reader.
42+
*
3943
* @psalm-type TOrder = array<string, "asc"|"desc">
4044
* @psalm-type TSortFieldItem = array<string, int>
4145
* @psalm-type TConfigItem = array{asc: TSortFieldItem, desc: TSortFieldItem, default: "asc"|"desc"}
@@ -131,6 +135,8 @@ private function __construct(private bool $ignoreExtraFields, array $config)
131135
/**
132136
* Create a sort instance that ignores the current order for extra logical fields that have no configuration.
133137
*
138+
* Recommended by default, especially for user input. Define the allowed logical fields in application code.
139+
*
134140
* @param array $config Logical fields config.
135141
* @psalm-param TUserConfig $config
136142
*
@@ -173,6 +179,10 @@ public static function only(array $config): self
173179
/**
174180
* Create a sort instance that uses logical field itself and direction provided when there is no configuration.
175181
*
182+
* The configuration is not an allowlist. Before passing untrusted input to {@see withOrder()} or
183+
* {@see withOrderString()}, validate field names against the fields your application allows. Unchecked field names
184+
* can lead to SQL injection when used with a database-backed reader. Prefer {@see only()} for user input.
185+
*
176186
* @param array $config Logical fields config.
177187
* @psalm-param TUserConfig $config
178188
*

0 commit comments

Comments
 (0)