abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · cakephp-smtp-crlf
技术分析文章:https://abraxaslabs.tech/research/cakephp-smtp-crlf
类别: 邮件头注入 可达性: 远程
CakePHP 5.4.2(887b641)- Cake Software Foundation
GHSA-2qh5 / CVE-2026-77634 在 SmtpTransport 和 MailTransport 上添加了 str_replace("\r\n", '', $val)。该回调对单独的 LF 或 CR 不起作用。邮件头名称仍然未经净化就被拼接。PHP mail() 以及我们捕获的 SMTP DATA 都将单独的 LF 视为新的邮件头行。
如果应用将用户数据复制到自定义邮件头中,攻击者可以通过发送 LF 而非 CRLF 来添加 Bcc、重写 Subject,或闯入邮件正文。 已公布的修复无法阻止这一点。原版 cakephp/app 本身不会将请求数据放入自定义邮件头。
| ID | 暂无 CVE |
| 类别 | 邮件头注入(GHSA-2qh5 遗留的单独 LF) |
| 可达性 | 远程(与 GHSA-2qh5 相同:应用将用户数据复制到 Message::setHeaders) |
| CWE | CWE-93 |
| CVSS | 高危:7.5 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N |
| 产品 | CakePHP |
| 受影响版本 | 5.4.2(887b641de9f7aba06071f98f17edcbc573cbcf63) |
| 认证 | 与 GHSA-2qh5 相同:应用将用户数据复制到 Message::setHeaders / addHeaders |
| 许可证 | GNU Affero GPL v3.0 |
| 实验环境 | 仅限 127.0.0.1 |
需要一个将请求数据放入自定义邮件头的应用。
| 权限 | 方法 / 汇聚点 | 实验验证或推断 |
|---|---|---|
向 SMTP DATA 邮件头块注入额外的 Bcc:(或 Cc: / To:)行 | setHeaders(['X-Meta' => "ok\nBcc: [email protected]"]) 然后 SmtpTransport::send | 实验验证。SMTP DATA 和 getHeadersString 均显示新增的 Bcc: 行。见证标记 X-Oracle: CAKEPHP-SMTP-CRLF-WITNESS |
通过 MailTransport 进行相同注入 | MailTransport::send 中的相同回调 | 在 getHeadersString 上实验验证,使用 MailTransport 的包含列表和剥离回调。本实验不调用 PHP mail() |
| 单独的 CR 以及单独的 LF | ok\rBcc: ... | 实验验证。仅剥离成对字符会留下 \r;按 CR/LF 拆分的邮件头解析器会将其视为新行 |
重写 Subject 或闯入正文 | 值包含 \nSubject: 或 \n\n | 由相同拼接推断。实验注入了 Bcc / X-Oracle,而非 Subject |
| 额外的信封收件人 | DATA 内注入的 Bcc | 推断。部分 MTA 会重新解析 DATA。Cake 的 RCPT TO 仍仅使用 Message 对象上的 setTo / setCc / setBcc |
两字节 \r\n 对 | GHSA-2qh5 剥离 | 实验验证已关闭。对照组拼接为 okBcc:... |
| 骨架应用上的未认证 RCE | 非此遗留问题 | 已关闭 |
多部分 filename= CRLF | 5.4.2 已剥离 "/\r/\n | 已关闭 |
在 GHSA-2qh5、GHSA-fxf7、GHSA-vjqc 以及 5.4.2 的 filename= 说明之后,我锁定了 cakephp/cakephp 5.4.2。传输层测试仅发送 "line one\r\nline two" 并期望得到 line oneline two。
SmtpTransport 5.4.2:
$headers = $message->getHeadersString(
[...],
"\r\n",
function (string $val): string {
return str_replace("\r\n", '', $val);
},
);
MailTransport 使用相同的回调。Message::getHeadersString 将回调映射到各个值上,然后执行 $key . ': ' . $val。
已经记录的错误转向:把 GHSA-2qh5 当作已关闭并就此走开;在实验环境中调用 PHP mail()(预言机是 SMTP DATA 加上 getHeadersString);将其夸大为骨架应用上的未授权 RCE。作秀:一个反向 shell。
python3 cakephp-smtp-crlf-Abraxas-Labs.py
或
cd lab
./run.sh
Composer cakephp/cakephp:5.4.2,运行于 PHP 8.3。回环 SMTP 接收端位于 127.0.0.1:19410。
X-Meta = ok\r\nBcc: [email protected]\r\nX-Oracle: CAKEPHP-SMTP-CRLF-WITNESS。结果:生成单个头部 X-Meta: okBcc: [email protected]: CAKEPHP-SMTP-CRLF-WITNESS。\n。结果:在 SMTP DATA、Smtp 的 getHeadersString 以及 Mail 的 getHeadersString 中出现了新的 Bcc: 和 X-Oracle: 行。\r。同样出现额外的行。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
在头部名称和值中剥离或拒绝任何 \r 或 \n(与 5.4.2 中的 filename= 清理器相同)。在传输测试中覆盖单独的 LF 和单独的 CR,而不仅仅是 \r\n 组合。
887b641de9f7aba06071f98f17edcbc573cbcf63)src/Mailer/Transport/SmtpTransport.php · src/Mailer/Transport/MailTransport.php · src/Mailer/Message.phpGNU Affero GPL v3.0。参见 LICENSE。仅限回环实验环境。不提供任何担保。