
CakePHP 5.4.2 - Élevé - À distance - CRLF - Content-Type de pièce jointe et résidu de Content-ID
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · cakephp-attachment-crlf
Classe : Injection d'en-tête de partie MIME Portée : Distante
CakePHP 5.4.2 (887b641) - Cake Software Foundation
5.4.2 supprime déjà ", \r et \n des name= / filename= multipart (FormDataPart::_headerParameterToString). C'est le contrôle. Content-Type et Content-ID ont été laissés en concaténation brute. Message::setAttachments copie le type média client d'un UploadedFile dans ce champ de type sans filtre supplémentaire.
Une application qui attache un upload utilisateur, ou qui transmet un contentId utilisateur, place ces octets sur la partie MIME. getBodyString() affiche alors une seconde ligne d'en-tête sous cette partie.
| ID | pas encore de CVE |
| Classe | Injection d'en-tête de partie MIME |
| Portée | Distante (application qui attache un upload utilisateur ou un contentId utilisateur) |
| CWE | CWE-93 |
| CVSS | Moyen : 5.4 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:N |
| Produit | CakePHP |
| Affecté | 5.4.2 (887b641de9f7aba06071f98f17edcbc573cbcf63) |
| Auth | application qui attache un upload utilisateur (MIME client UploadedFile) ou un contentId utilisateur |
| Licence | GNU Affero GPL v3.0 |
| Lab | 127.0.0.1 uniquement |
Quelqu'un capable d'influencer les métadonnées de pièce jointe que l'application transmet à Message::setAttachments / addAttachment peut injecter des en-têtes de partie MIME.
| Privilège | Méthode / sink | Type | Prouvé en lab ou déduit |
|---|---|---|---|
Ligne d'en-tête Content-Type supplémentaire | setAttachments avec 'mimetype' => "text/plain\\r\\nX-Injected: …" | Intégrité des en-têtes de partie MIME | Prouvé en lab. Ligne témoin présente |
Ligne d'en-tête Content-ID supplémentaire | 'contentId' => "cid@…>\\r\\nX-Injected: …" (partie inline) | Intégrité des en-têtes de partie MIME | Prouvé en lab. Ligne témoin présente |
| Même injection via le MIME d'upload | UploadedFile::getClientMediaType() copié sur mimetype | Intégrité des en-têtes de partie MIME | Prouvé en lab. Ligne témoin présente |
CRLF dans filename= | nom de pièce jointe avec CR/LF | Fermé | Prouvé fermé en lab. Le strip de 5.4.2 tient |
RCPT d'enveloppe / Bcc via ce sink | en-têtes de partie MIME dans le corps | Fermé | C'est le strip pair-only de SmtpTransport, un cas voisin |
| Envoi SMTP | le lab appelle uniquement getBodyString() | Fermé | Pas de transport, pas de shell |
Déduit de la même concaténation, non démontré : un type ou contentId forgé qui inclut une boundary multipart pourrait découper le message en parties supplémentaires dans un MUA récepteur. Je n'ai pas envoyé de mail.
Autres restes du même pin : window SQLi, collate SQLi, cache unserialize.
J'ai épinglé cakephp/cakephp 5.4.2 après la note de la bakery indiquant que l'injection multipart Content-Disposition filename= était corrigée. _headerParameterToString est le sanitizer :
$transliterated = Text::transliterate(str_replace(['"', "\r", "\n"], '', $value));
__toString() fait toujours :
if ($this->type) {
$out .= 'Content-Type: ' . $this->type . "\r\n";
}
if ($this->contentId) {
$out .= 'Content-ID: <' . $this->contentId . ">\r\n";
}
Message::setAttachments copie le type client de l'upload sans strip. attachFiles / attachInlineFiles appellent ensuite $part->type($fileInfo['mimetype']) et $part->contentId($fileInfo['contentId']).
Fausses pistes déjà consignées : traiter le RCPT d'enveloppe comme ce reste (la ligne supplémentaire est dans le corps) ; prétendre que filename= injecte encore (ce n'est pas le cas) ; envoyer du SMTP ; un reverse shell. Du théâtre.
python3 cakephp-attachment-crlf-Abraxas-Labs.py
ou
cd lab
./run.sh
Cible uniquement http://127.0.0.1:19460. PHP 8.3, tag CakePHP 5.4.2 cloné au build. lab_server.php expose Message::setAttachments. Quatre cas : contrôle filename, mimetype, contentId, type média UploadedFile.
SUCCESS cakephp-attachment-crlf how=live pin=5.4.2 sha=887b641de9f7aba06071f98f17edcbc573cbcf63 mimetype=yes contentId=yes upload=yes filename-stripped=yes CAKEPHP-ATTACHMENT-CRLF-WITNESS
Faire passer type, contentId et transferEncoding par le même strip " / \r / \n que _headerParameterToString. Rejeter la valeur si elle contient encore un saut de ligne après le strip. Couvrir le MIME client d'UploadedFile et les mimetype / contentId explicites dans les tests du mailer, pas seulement filename=.
887b641de9f7aba06071f98f17edcbc573cbcf63)FormDataPart.php · Message.phpfilename= de la bakery 5.4.2GNU Affero GPL v3.0. Voir LICENSE. Lab en loopback uniquement. Aucune garantie.