
CakePHP 5.4.2 - Alta - Remota - SQLi - COLLATE collation é um fragmento SQL bruto
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · cakephp-collate-sqli
Classe: SQLi Alcance: Remoto
CakePHP 5.4.2 (887b641) - Cake Software Foundation
StringExpression::sql vincula o valor da string e concatena a collation. IdentifierExpression faz o mesmo. Não existe ensureSimpleString. O quoteIdentifier do Postgres é '"' . trim($collation, '"') . '"', então uma aspa embutida fecha o CAST prematuramente.
Uma aplicação que repassa a collation de requisição/locale para new StringExpression($term, $collation) coloca essa string no COLLATE. O valor permanece vinculado. A collation não.
| ID | ainda sem CVE |
| Classe | SQLi |
| Alcance | Remoto (aplicação que repassa collation/locale para StringExpression / IdentifierExpression) |
| CWE | CWE-89 |
| CVSS | Alto: 8.1 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N |
| Produto | CakePHP (cakephp/database) |
| Afetado | 5.4.2 (887b641de9f7aba06071f98f17edcbc573cbcf63) |
| Autenticação | aplicação que repassa collation/locale para esses construtores |
| Licença | GNU Affero GPL v3.0 |
| Lab | apenas 127.0.0.1 |
Requer uma aplicação que passe a collation de usuário/locale para esses construtores. O cakephp/app padrão não expõe collation em um formulário público por si só.
| Privilégio | Método / sink | Tipo | Comprovado em lab ou inferido |
|---|---|---|---|
Inserir SQL após COLLATE | StringExpression::sql concatena $this->collation | Integridade do SQL compilado | Comprovado em lab. O SQL bruto contém o payload não vinculado |
| Mesma inserção em identificadores | IdentifierExpression note COLLATE <payload> | Integridade do SQL compilado | Comprovado em lab. id_raw_sql contém o payload |
Escapar do encapsulamento "..." do Postgres | quoteIdentifier = '"' . trim($collation, '"') . '"' | Integridade do SQL compilado | Comprovado em lab. O SQL compilado é COLLATE "C" AS text)) || (SELECT ... |
| Executar o escape e ler outra tabela | CAST(... ) || (SELECT note FROM lab_secret ...) | Reconhecimento do BD | Comprovado em lab. Resultado xCAKEPHP-COLLATE-SQLI-WITNESS, sem erro de execução |
| Modificar linhas / mais SQL com o papel da conexão | Mesma injeção | Integridade do BD | Inferido. O lab é um oráculo SELECT |
| Controle negativo | collation C | Fechado | Comprovado em lab. Resultado x, sem witness, compilado COLLATE "C" |
Fechado neste resíduo: valor de string vinculado (:c0 permanece o literal x); uma collation que passaria em ensureSimpleString (^[a-zA-Z0-9]+$) não é este payload. Não é RCE não autenticado em uma aplicação esqueleto. Não é um shell.
Outros resíduos do mesmo pin: window SQLi, attachment CRLF, cache unserialize.
Fiz o pin em 5.4.2 após as notas de FunctionsBuilder / filename=. Dez buscas. A passagem de SQLi restante é esta. StringExpression::sql:
$placeholder = $binder->placeholder('c');
$binder->bind($placeholder, $this->string, 'string');
return $placeholder . ' COLLATE ' . $this->collation;
O quoteIdentifier do Postgres encapsula com aspas ASCII e trim($collation, '"'). Uma " embutida fecha o identificador. -- consome o fechamento restante que o Cake ainda acrescenta.
Caminhos errados já registrados: SQLite como único driver (a concatenação é real, o escape do encapsulamento é do Postgres); tratar o valor vinculado como a injeção; afirmar que ensureSimpleString já rodou aqui (não rodou); um reverse shell. Teatro.
python3 cakephp-collate-sqli-Abraxas-Labs.py
ou
cd lab
./run.sh
Alvo apenas http://127.0.0.1:19450. cakephp/database 5.4.2 mais Postgres 16. Aplicação mínima repassa ?collation= para StringExpression / IdentifierExpression e executa CAST(... AS text). A tabela secreta contém o witness.
SUCCESS cakephp-collate-sqli pin=5.4.2 raw=concat pg-wrap=breakout exec=yes CAKEPHP-COLLATE-SQLI-WITNESS
ensureSimpleString() (ou uma allowlist de collation) no argumento de collation. O Postgres deve citar identificadores corretamente, não trim mais encapsulamento.
887b641de9f7aba06071f98f17edcbc573cbcf63)StringExpression.php · IdentifierExpression.php · Postgres.phpensureSimpleString()GNU Affero GPL v3.0. Veja LICENSE. Apenas lab em loopback. Sem garantia.