
CakePHP 5.4.2 - Alta - Remoto - Injeção de cabeçalho - SmtpTransport LF isolado remanescente de GHSA-2qh5
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · cakephp-smtp-crlf
Write-up: https://abraxaslabs.tech/research/cakephp-smtp-crlf
Classe: Injeção de cabeçalho de e-mail Alcance: Remoto
CakePHP 5.4.2 (887b641) - Cake Software Foundation
GHSA-2qh5 / CVE-2026-77634 adicionou str_replace("\r\n", '', $val) em SmtpTransport e MailTransport. Esse callback é um no-op para um LF ou CR isolado. Os nomes de cabeçalho ainda são concatenados sem sanitização. O mail() do PHP e o SMTP DATA que capturamos tratam um LF isolado como uma nova linha de cabeçalho.
Se um app copia dados do usuário para um cabeçalho personalizado, um atacante pode adicionar Bcc, reescrever o Subject ou invadir o corpo enviando LF em vez de CRLF. A correção anunciada não impede isso. O cakephp/app padrão não coloca dados de requisição em cabeçalhos personalizados por conta própria.
| ID | ainda sem CVE |
| Classe | Injeção de cabeçalho de e-mail (resíduo de LF isolado do GHSA-2qh5) |
| Alcance | Remoto (igual ao GHSA-2qh5: o app copia dados do usuário para Message::setHeaders) |
| CWE | CWE-93 |
| CVSS | Alto: 7.5 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N |
| Produto | CakePHP |
| Afetado | 5.4.2 (887b641de9f7aba06071f98f17edcbc573cbcf63) |
| Autenticação | igual ao GHSA-2qh5: o app copia dados do usuário para Message::setHeaders / addHeaders |
| Licença | GNU Affero GPL v3.0 |
| Lab | apenas 127.0.0.1 |
Requer uma aplicação que coloque dados de requisição em cabeçalhos de e-mail personalizados.
| Privilégio | Método / sink | Comprovado em lab ou inferido |
|---|---|---|
Injetar uma linha Bcc: extra (ou Cc: / To:) no bloco de cabeçalhos do SMTP DATA | setHeaders(['X-Meta' => "ok\nBcc: [email protected]"]) e então SmtpTransport::send | Comprovado em lab. O SMTP DATA e o getHeadersString mostram ambos uma nova linha Bcc:. Testemunha X-Oracle: CAKEPHP-SMTP-CRLF-WITNESS |
Mesma injeção através do MailTransport | Mesmo callback em MailTransport::send | Comprovado em lab no getHeadersString com a lista de inclusão e o callback de strip do MailTransport. Este lab não chama o mail() do PHP |
| CR isolado, assim como LF isolado | ok\rBcc: ... | Comprovado em lab. O strip apenas de pares deixa \r; parsers de cabeçalho que dividem em CR/LF tratam isso como uma nova linha |
Reescrever o Subject ou invadir o corpo | Valor contém \nSubject: ou \n\n | Inferido a partir da mesma concatenação. O lab injetou Bcc / X-Oracle, não Subject |
| Destinatário extra no envelope | Bcc injetado dentro do DATA | Inferido. Alguns MTAs reanalisam o DATA. O RCPT TO do Cake ainda usa apenas setTo / setCc / setBcc no objeto Message |
Par \r\n de dois bytes | Strip do GHSA-2qh5 | Comprovado em lab como fechado. O controle concatena okBcc:... |
| RCE não autenticado em um app skeleton | não é este resíduo | Fechado |
CRLF em filename= multipart | 5.4.2 já remove "/\r/\n | Fechado |
Fixe a versão cakephp/cakephp 5.4.2 após GHSA-2qh5, GHSA-fxf7, GHSA-vjqc e a nota sobre filename= da 5.4.2. Os testes de transporte apenas enviam "line one\r\nline two" e esperam line oneline two.
SmtpTransport 5.4.2:
$headers = $message->getHeadersString(
[...],
"\r\n",
function (string $val): string {
return str_replace("\r\n", '', $val);
},
);
MailTransport usa o mesmo callback. Message::getHeadersString mapeia o callback sobre os valores e, em seguida, faz $key . ': ' . $val.
Caminhos errados já registrados: tratar o GHSA-2qh5 como encerrado e ir embora; chamar o mail() do PHP no laboratório (o oráculo é SMTP DATA mais getHeadersString); inflar isso para RCE não autenticado em um app esqueleto. Teatro: um reverse shell.
python3 cakephp-smtp-crlf-Abraxas-Labs.py
ou
cd lab
./run.sh
Composer cakephp/cakephp:5.4.2 em PHP 8.3. Sink SMTP de loopback em 127.0.0.1:19410.
X-Meta = ok\r\nBcc: [email protected]\r\nX-Oracle: CAKEPHP-SMTP-CRLF-WITNESS. Resultado: um cabeçalho X-Meta: okBcc: [email protected]: CAKEPHP-SMTP-CRLF-WITNESS.\n. Resultado: novas linhas Bcc: e X-Oracle: no SMTP DATA, no getHeadersString do Smtp e no getHeadersString do Mail.\r. As mesmas linhas extras.SUCCESS cakephp-smtp-crlf pin=5.4.2 control-crlf-stripped=yes lf-bcc=yes cr-leftover=yes how=smtp-data-bcc-line CAKEPHP-SMTP-CRLF-WITNESS
Remova ou rejeite qualquer \r ou \n em nomes e valores de cabeçalhos (o mesmo que o sanitizador de filename= da 5.4.2). Cubra LF isolado e CR isolado nos testes de transporte, não apenas o par \r\n.
887b641de9f7aba06071f98f17edcbc573cbcf63)src/Mailer/Transport/SmtpTransport.php · src/Mailer/Transport/MailTransport.php · src/Mailer/Message.phpGNU Affero GPL v3.0. Consulte LICENSE. Apenas laboratório em loopback. Sem garantias.