01เกิดอะไรขึ้น
Laravel เป็น PHP framework ที่ใช้ทำเว็บ ระบบหลังบ้าน และ API ของแอปมือถือกันมากในไทย ช่องโหว่นี้อยู่ใน ตัว framework ส่วนที่ตรวจ API token ของผู้ใช้ แอปที่เปิด API ให้แอปมือถือหรือระบบภายนอกเรียกด้วย token จึงเสี่ยงที่สุด ถ้าไม่มีทีมคอยติดตามเรื่องนี้ ดูบริการดูแลความปลอดภัยเว็บไซต์และแอปรายเดือน
ปกติ TokenGuard รับ token จาก query string, body ของ request หรือ header แล้วค้นหาผู้ใช้ที่มี token ตรงกันในฐานข้อมูล ปัญหาคือโค้ดไม่ได้ตรวจว่าค่าที่รับมาเป็นข้อความ เมื่อผู้โจมตีส่งค่าที่ไม่ใช่ข้อความ ฐานข้อมูล MySQL และ MariaDB บางการตั้งค่าตีความแล้วจับคู่ไปเป็นผู้ใช้คนอื่น ผลคือ ล็อกอินเป็นผู้ใช้ที่มีอยู่ในระบบได้ รวมถึงผู้ดูแลระบบถ้าบัญชีนั้นใช้ guard เดียวกัน
ทีม Laravel แก้โดยเพิ่มการตรวจว่า token ต้องเป็นข้อความก่อนค้นหา ตัวแก้ไขออกไปในรุ่น 12.68.0 และ 13.29.0 เมื่อ 25 ส.ค. 2569 แล้วจึงประกาศเป็นช่องโหว่ภายหลังเมื่อ 19 ต.ค. 2569 ใครอัปเดตสาย 12 หรือ 13 เป็นประจำจึงได้รับการแก้ไขไปแล้ว ส่วนแอปที่ยังอยู่บน Laravel 11 หรือเก่ากว่าไม่ได้รับการแก้ไขเลย
02ใครได้รับผลกระทบ
แอปจะโดนเมื่อเข้าเงื่อนไข ครบทั้ง 3 ข้อ
| เงื่อนไข | เช็คจากตรงไหน |
|---|---|
| 1. Laravel รุ่นก่อน 12.68.0 หรือ 13.0 – 13.28 | php artisan --version หรือ composer.lock |
2. มี guard ที่ตั้ง 'driver' => 'token' | config/auth.php ส่วน guards |
| 3. ใช้ MySQL หรือ MariaDB | DB_CONNECTION ในไฟล์ .env |
ทำไมแอป Laravel รุ่นเก่ามักเข้าเงื่อนไขข้อ 2
โปรเจกต์ที่สร้างด้วย Laravel 5.8 ถึง 7 มี guard ชื่อ api ที่ใช้ driver token อยู่ใน config/auth.php ตั้งแต่ติดตั้ง Laravel 8 เป็นรุ่นแรกที่เอาออก แต่โปรเจกต์ที่อัปเกรดต่อมาจากรุ่นเก่ามักยังเก็บไว้ และ route ไหนที่ใช้ middleware auth:api ก็จะใช้ guard นี้ทันที
สิ่งที่ไม่อยู่ในขอบเขตของ CVE นี้
- การล็อกอินหน้าเว็บด้วย session (guard
web) - Laravel Sanctum และ Laravel Passport ซึ่งใช้ guard ของตัวเอง การแก้ไขในรุ่น 12.68.0 แก้เฉพาะไฟล์ TokenGuard ของ framework
ถึงอย่างนั้น หลายโปรเจกต์ใช้ Sanctum สำหรับแอปใหม่แต่ยังมี guard แบบ token ค้างอยู่ใน config ควรเช็คทุกโปรเจกต์ด้วยคำสั่งในหัวข้อ วิธีเช็ค
03รุ่นที่แก้แล้ว และระยะ security fix ของแต่ละรุ่น
| สาย | รุ่นที่แก้แล้ว | Security fix ถึง | PHP ที่รองรับ | คำแนะนำ |
|---|---|---|---|---|
| Laravel 13 | 13.29.0 | 17 มี.ค. 2571 | 8.3 – 8.5 | อัปเดตเป็นรุ่นล่าสุดของสาย 13 ได้เลย |
| Laravel 12 | 12.68.0 | 24 ก.พ. 2570 | 8.2 – 8.5 | อัปเดตได้เลย แต่ควรวางแผนขึ้น 13 ก่อน ก.พ. 2570 |
| Laravel 11 | ไม่มี | หมดแล้ว 12 มี.ค. 2569 | 8.2 – 8.4 | อุดชั่วคราว แล้วอัปเกรดเป็น 12 หรือ 13 |
| Laravel 10 | ไม่มี | หมดแล้ว 4 ก.พ. 2568 | 8.1 – 8.3 | อุดชั่วคราว แล้วอัปเกรด |
| Laravel 9 | ไม่มี | หมดแล้ว 6 ก.พ. 2567 | 8.0 – 8.2 | อุดชั่วคราว แล้วอัปเกรด (ต้องเปลี่ยน PHP ด้วย) |
| Laravel 8 และเก่ากว่า | ไม่มี | หมดแล้ว 24 ม.ค. 2566 | 7.3 – 8.1 | อุดชั่วคราว แล้วอัปเกรด PHP และ Laravel พร้อมกัน |
ระยะ security fix และ PHP ที่รองรับมาจากตาราง Support Policy ทางการของ Laravel ส่วนรุ่นล่าสุด ณ วันที่เขียนคือ 13.39.0 และ 12.70.2 ซึ่งรวมการแก้ไขนี้แล้ว
04วิธีเช็คว่าแอปโดนหรือไม่
รันในโฟลเดอร์ของโปรเจกต์บนเซิร์ฟเวอร์ ทั้ง 4 คำสั่งอ่านอย่างเดียว ไม่เปลี่ยนแปลงระบบ
php artisan --version
grep -n "'driver'" config/auth.php
ถ้าเห็นบรรทัด 'driver' => 'token' แปลว่ามี guard แบบนี้อยู่ ให้เช็คต่อว่ามี route ใช้หรือไม่
grep -rn "auth:api\|guard('api')" routes appgrep -n "^DB_CONNECTION" .env composer audit
composer audit จะแสดง CVE-2026-114509 ถ้ารุ่นที่ติดตั้งยังไม่แก้ รวมถึงช่องโหว่ของ library อื่นในโปรเจกต์ด้วย คำสั่งนี้มีใน Composer 2.4 ขึ้นไป
05วิธีแก้ Laravel 12 และ 13
composer update laravel/framework --with-all-dependencies php artisan --version php artisan optimize:clear
รุ่นที่ได้ต้องเป็น 12.68.0 หรือ 13.29.0 ขึ้นไป จากนั้นรีสตาร์ต PHP-FPM และ process ที่รันค้าง เพื่อให้โหลดโค้ดใหม่
sudo systemctl restart php8.3-fpm
php artisan queue:restart
# ถ้าใช้ Octane
php artisan octane:reloadถ้า deploy ด้วย Docker ให้ build image ใหม่จาก composer.lock ที่อัปเดตแล้ว การรีสตาร์ต container อย่างเดียวไม่ได้เปลี่ยนโค้ด
06Laravel 8–11 ที่ไม่มีแพตช์
รุ่นเหล่านี้พ้นระยะ security fix แล้ว จะไม่มีรุ่นแก้ไขออกมา ทางเลือกเรียงจากเร็วที่สุดไปถึงถาวร
ทางที่ 1: ไม่ได้ใช้ guard แบบ token ให้เอาออก
ถ้าคำสั่งเช็คข้อ 3 ไม่พบ route ใดใช้ auth:api ให้ลบ guard ที่ใช้ driver token ออกจาก config/auth.php แล้วรัน php artisan config:clear ถ้ามีโค้ดเรียก guard นี้อยู่ จะเห็น error ทันทีระหว่างทดสอบ
ทางที่ 2: ใช้อยู่ ให้อุดด้วย middleware ชั่วคราว
middleware นี้ทำแบบเดียวกับที่ทีม Laravel แก้ คือปฏิเสธ request ที่ส่ง api_token มาเป็นค่าที่ไม่ใช่ข้อความ ก่อนจะถึง TokenGuard
<?php namespace App\Http\Middleware; use Closure; use Illuminate\Http\Request; // Temporary fix for CVE-2026-114509 on Laravel versions without a patch. // Change 'api_token' if config/auth.php sets a different 'input_key'. class RejectNonStringApiToken { public function handle(Request $request, Closure $next) { $token = $request->input('api_token'); if ($token !== null && ! is_string($token)) { abort(401); } return $next($request); } }
ลงทะเบียนเป็น global middleware ให้ทำงานก่อนการยืนยันตัวตนทุก route
protected $middleware = [
\App\Http\Middleware\RejectNonStringApiToken::class,
// ... middleware เดิม
];->withMiddleware(function (Middleware $middleware) {
$middleware->prepend(\App\Http\Middleware\RejectNonStringApiToken::class);
})ถ้าโค้ดเรียก Auth::guard('api')->validate() ด้วยค่าที่ไม่ได้มาจาก api_token ของ request ให้ตรวจ is_string() ก่อนส่งเข้าไปด้วย
ทางที่ 3: อัปเกรดเป็น Laravel 12 หรือ 13 (ทางแก้ถาวร)
Laravel 12 ต้องใช้ PHP 8.2 ขึ้นไป และ Laravel 13 ต้องใช้ PHP 8.3 ขึ้นไป แอปบน Laravel 8 หรือ 9 ส่วนใหญ่ยังรันบน PHP 7.4 ถึง 8.1 ซึ่งไม่มีรุ่นแก้ไข PHP2Shell จากทีม PHP การอัปเกรดจึงมักต้องทำทั้ง PHP และ Laravel พร้อมกัน ไล่ทีละรุ่นหลัก และทดสอบทุกหน้าจอที่สำคัญ
07ช่องโหว่อื่นของ Laravel ในรอบเดียวกัน
| CVE | ระดับ | รายละเอียด | รุ่นที่แก้แล้ว |
|---|---|---|---|
| CVE-2026-114509 | Critical | TokenGuard ถูกข้ามการยืนยันตัวตนด้วยค่า token ที่ไม่ใช่ข้อความ (คู่มือนี้) | 12.68.0 · 13.29.0 |
| CVE-2026-114508 | Medium | การดึงข้อมูลความสัมพันธ์ (relationship inclusion) อาจทำให้ข้อมูลถูกลบโดยไม่ได้รับอนุญาต กระทบ 12.45.0 ขึ้นไปและสาย 13 | 12.68.0 · 13.27.0 |
| CVE-2026-102279 | Low | XSS ในหน้าแสดงข้อมูล debug ประกาศ 29 ก.ย. 2569 ถ้า production ตั้ง APP_DEBUG=false ไว้แล้วจะไม่เห็นหน้านี้ | 12.69.0 · 13.30.0 |
อัปเดตเป็นรุ่นล่าสุดของสาย 12 หรือ 13 ครั้งเดียวได้การแก้ไขครบทั้ง 3 รายการ
08คำถามที่พบบ่อย
09แหล่งอ้างอิง
- GitHub Advisory GHSA-f9x3-7vq9-cph6 (CVE-2026-114509): Laravel TokenGuard authentication bypass through non-string API credentials
- laravel/framework: การแก้ไขใน TokenGuard ระหว่าง v12.67.0 และ v12.68.0
- GitHub Advisory GHSA-5wcm-3v2w-8362 (CVE-2026-114508): Laravel relationship inclusion can trigger unauthorized data destruction
- GitHub Advisory GHSA-jh5r-qr3c-85q8 (CVE-2026-102279): Laravel XSS in Debug Page Information
- Laravel: Release Notes และ Support Policy (ช่วงเวลา security fix ของแต่ละรุ่น)
- Laravel 10.x Release Notes: Support Policy ของ Laravel 8–11
- laravel/laravel 7.x: config/auth.php (guard api แบบ token เป็นค่าเริ่มต้น)
- Packagist: laravel/framework (รุ่นและวันออก)
- CISA: Known Exploited Vulnerabilities Catalog
ข้อมูลในคู่มือนี้รวบรวมจากประกาศของ Laravel, GitHub Advisory Database และตาราง Support Policy ทางการ ณ 27 ต.ค. 2569 เวลา 23:30 น. สถานการณ์อาจเปลี่ยนแปลง โปรดตรวจประกาศล่าสุดก่อนดำเนินการ คู่มือนี้ไม่มีรายละเอียดวิธีโจมตี