JFrog แกะ CVE ระดับ Critical 6 ตัวของ SQLite แล้วพบว่าไม่มีอยู่จริง — ฟังก์ชันที่อ้างยังไม่ถูกเขียน เลขบรรทัดเกินความยาวไฟล์ และ PoC ไม่ทำให้แครชสักตัว
เมื่อวานเราเขียนถึงรายงาน VulnCheck ที่วัดว่าช่องโหว่ซึ่ง AI ค้นเจอนับพันรายการ สุดท้ายถูกใช้โจมตีจริงแค่ 1.3% — คำถามที่รายงานนั้นตอบคือ “ช่องโหว่ที่ AI หาเจอสำคัญแค่ไหน” วันนี้มีงานอีกชิ้นที่ถามคำถามที่แสบกว่านั้น: แล้วมันเป็นช่องโหว่จริงหรือเปล่า
โพสต์ของ Afek Berger นักวิจัยจาก JFrog Security Research (เผยแพร่ 30 กรกฎาคม 2026 — เราเขียนถึงช้าไปห้าวัน แต่มันเพิ่งขึ้นอันดับหนึ่ง Hacker News เมื่อวาน) เล่าเรื่องที่ตรงไปตรงมามาก มีรีโป GitHub ที่เพิ่งสร้างใหม่ชื่อ programmervuln/cveadvisory- ปล่อยชุด advisory ช่องโหว่ SQLite ออกมา NVD จัดให้เป็น Critical อย่างรวดเร็ว และ ADP ของ CISA ก็เห็นด้วย แต่พอ JFrog ลงไปตรวจจริง ทุกอย่างพังทั้งกอง
หกรายการที่ถูกแกะ
| CVE | ช่องโหว่ที่อ้าง | CVSS | สิ่งที่ JFrog พบ |
|---|---|---|---|
| CVE-2026-51302 | UAF ใน exprComputeOperands() | 9.8 CRITICAL | อ้างฟังก์ชันที่ไม่มีอยู่ |
| CVE-2026-51303 | UAF ใน back-ref ของ ExprListDelete() | 9.8 CRITICAL | อ้างแพตช์ที่ไม่มีอยู่ |
| CVE-2026-51300 | UAF ใน sqlite3ExprDelete() | 9.1 CRITICAL | เลขบรรทัดชี้ไปโค้ดที่ไม่เกี่ยวข้อง |
| CVE-2026-51297 | UAF ผ่าน jsonBlobEdit() | 8.8 HIGH | อ้างฟังก์ชันที่ไม่มีอยู่ |
| CVE-2026-51296 | UAF ใน jsonRemoveFunc | 7.5 HIGH | เลขบรรทัดที่อ้างไม่มีอยู่จริง |
| CVE-2026-51304 | UAF จาก pOrderBy->nExpr หลัง free | 7.5 HIGH | ฟังก์ชันมีจริงแต่จำนวนอาร์กิวเมนต์ผิด |
และ JFrog เชื่อว่า advisory อีกกว่า 50 รายการ ในรีโปเดียวกันก็เป็นของแต่งเช่นกัน ยกเว้นเพียงหนึ่งรายการ
วิธีตรวจ — จุดที่ทำให้งานชิ้นนี้น่าเชื่อ
สิ่งที่ทำให้โพสต์นี้ต่างจากการ “เดาว่าเป็น AI เขียน” คือ JFrog ไม่ได้เดา เขาวางกระบวนการตรวจสี่ขั้น: โคลนรีโป sqlite/sqlite อย่างเป็นทางการแล้ว checkout แท็กเป้าหมาย (version-3.41.0, 3.51.2, 3.51.3) เทียบกลไกที่อ้างกับซอร์สจริง, คอมไพล์รีลีสทางการใน Docker container แยกเพื่อกัน environment ปนเปื้อน, ป้อน PoC SQL ของแต่ละ advisory เข้าไปตรง ๆ ในไบนารีที่คอมไพล์ด้วย AddressSanitizer (ASan) และตรวจ metadata กับ CPE บนฟีด NVD และ GHSA
ผลของแต่ละรายการอ่านแล้วน่าตกใจในความหยาบ:
CVE-2026-51302 (9.8) อ้างว่า sqlite3ReleaseTempReg() ทิ้ง dangling pointer ไว้ใน regFree1 แล้วถูก deref โดย exprComputeOperands() — ปัญหาคือ exprComputeOperands() ยังไม่มีอยู่ใน SQLite 3.41 มันถูกเพิ่มกลางปี 2025 และยิ่งกว่านั้น sqlite3ReleaseTempReg() ไม่ได้ยุ่งกับ heap เลย มันแค่รีไซเคิลเลข register กลับเข้าอาร์เรย์ ทำให้ UAF เป็นไปไม่ได้โดยการออกแบบ
CVE-2026-51303 (9.8) อ้างว่าแพตช์อยู่ใน 3.51.3 — แต่ diff ระหว่าง 3.51.2 กับ 3.51.3 ไม่มีการแก้ src/expr.c เลยแม้แต่บรรทัดเดียว แพตช์ที่อ้างถึงถูกแต่งขึ้นทั้งหมด ส่วน PoC เป็น SQL ที่ผิดไวยากรณ์ ตายตั้งแต่ชั้น parser
CVE-2026-51296 (7.5) ระบุว่าบั๊กอยู่ที่บรรทัด 3555 และ 3575 ของ json.c — ในเวอร์ชัน 3.41.0 ไฟล์นั้น ยาวแค่ 2,706 บรรทัด
CVE-2026-51300 (9.1) อ้างบรรทัด 1012 และ 1026 ซึ่งเมื่อไปดูจริงพบว่าบรรทัดหนึ่งเป็นคอมเมนต์ อีกบรรทัดเป็นการเรียกจองหน่วยความจำ ไม่เกี่ยวกับ pLeft หรือ logic การลบเลย
PoC ทุกตัวรันแล้วไม่มีตัวไหนทำให้แครช บางตัวคืนผลลัพธ์ปกติโดยไม่มี memory leak ด้วยซ้ำ
ปมที่ใหญ่กว่าตัว CVE — กระบวนการที่ไม่มีคนเฝ้า
JFrog ชี้ไปที่โครงสร้าง ไม่ใช่แค่ผู้ก่อเหตุ ประโยคที่คมที่สุดในโพสต์คือ “กระบวนการยื่น CVE ผ่านฟอร์มสาธารณะของ MITRE ไม่มีการยืนยันตัวตนจริงจังใด ๆ” ประกอบกับข้อเท็จจริงว่า ตั้งแต่กุมภาพันธ์ 2024 NIST หยุดทำการวิเคราะห์เชิงลึกด้วยมือกับ CVE ที่ไหลเข้ามา เมื่อไม่มีการบังคับให้แนบ PoC ที่ใช้งานได้ และไม่มีการยืนยันกับผู้ดูแลโปรเจกต์ advisory ที่แต่งขึ้นจึงไหลผ่าน GHSA, NVD และเข้าไปถึงเครื่องมือสแกนขององค์กรได้สบาย ๆ
มีรายละเอียดหนึ่งที่บอกอะไรได้เยอะ: ตอน JFrog กำลังตรวจ CVE-2026-51302 อยู่ Red Hat ให้คะแนน 10.0 Critical พอกลับมาดูอีกวันคะแนนถูกลดเหลือ 7.6 High — ระบบมีการแก้ตัวเอง แต่ช้ากว่าการแพร่กระจายมาก
อีกสัญญาณที่ตรวจง่ายและ JFrog เน้นคือ ไม่มี CVE รายการไหนเลยปรากฏบนหน้า advisory อย่างเป็นทางการของ SQLite เอง ซึ่งเป็นแหล่งที่โปรเจกต์นี้ดูแลอย่างเข้มงวดมาตลอด
จุดที่ควรอ่านอย่างระวัง
หลักฐานในโพสต์นี้แข็งแรงมากในส่วนที่เป็นเทคนิค — การเทียบซอร์สโค้ด การ diff เวอร์ชัน และการรัน PoC ใต้ ASan เป็นสิ่งที่ใครก็ทำซ้ำได้และเถียงยาก
แต่มีข้ออ้างหนึ่งที่อ่อนกว่าที่เหลือ: JFrog บอกว่านำ advisory ไปทดสอบกับ Gptzero แล้วถูกตีว่าเป็นข้อความที่เครื่องสร้าง เครื่องมือตรวจจับ “ข้อความที่ AI เขียน” เป็นเทคโนโลยีที่มีอัตราผิดพลาดสูงและถูกวิจารณ์หนักมาตลอด ถ้าหลักฐานทั้งชิ้นวางอยู่บนตรงนี้ก็คงเชื่อไม่ได้ — โชคดีที่มันไม่ใช่ สิ่งที่พิสูจน์ว่า advisory เหล่านี้เป็นของปลอมคือฟังก์ชันที่ไม่มีอยู่และไฟล์ที่สั้นกว่าเลขบรรทัดที่อ้าง ไม่ใช่ผลจาก Gptzero ควรอ่านส่วนนั้นเป็นของแถม ไม่ใช่ของหลัก
และควรระวังการสรุปเกินหลักฐานอีกข้อ: โพสต์นี้ไม่ได้พิสูจน์ว่า “AI หาช่องโหว่ไม่ได้” — มันพิสูจน์ว่า ใครบางคนใช้ AI ผลิตเอกสารที่ดูเหมือน advisory แล้วยื่นเข้าระบบที่ไม่มีคนตรวจ ซึ่งเป็นคนละเรื่องกัน
มุมมอง AI Curator
สองข่าวในสองวันประกอบกันเป็นภาพที่ควรทำให้ทุกคนหยุดคิด เมื่อวาน VulnCheck บอกว่าช่องโหว่ที่ AI หาเจอ ถูกใช้โจมตีจริงน้อยมาก วันนี้ JFrog บอกว่าบางส่วน ไม่ใช่ช่องโหว่ตั้งแต่แรก ตัวเลข “เราหาเจอ N ช่องโหว่” ซึ่งเป็นตัวเลขที่ทุกแล็บชอบประกาศ จึงกำลังเสื่อมค่าลงพร้อมกันจากทั้งสองด้าน
แต่สิ่งที่ผมคิดว่าน่ากังวลที่สุดไม่ใช่ CVE ปลอมหกตัว มันคือ ต้นทุนที่ไม่สมมาตรอย่างสุดขั้ว ฝั่งผลิต advisory ปลอมใช้เวลาไม่กี่นาทีต่อชิ้นและแทบไม่มีต้นทุน ส่วนฝั่งหักล้างต้องโคลนรีโป checkout สามแท็ก คอมไพล์ใน Docker รัน ASan และอ่านซอร์สทีละฟังก์ชัน — งานของวิศวกรที่มีทักษะเป็นวัน ๆ ต่อ CVE หนึ่งตัว ระบบไหนก็ตามที่ฝั่งสร้างขยะถูกกว่าฝั่งเก็บกวาดเป็นพันเท่า ระบบนั้นจะถูกถล่มจนล่ม นี่คือกลไกเดียวกับที่ทำให้กล่องรับ bug bounty ของ Apple ตันจนรายงานช่องโหว่ macOS ของจริงหลุดรอดไป
สำหรับทีมในไทย เรื่องนี้ไม่ใช่ข่าวไกลตัวเลย เพราะมันเข้ามาถึงเราผ่านช่องทางที่เราไม่ได้เลือกเอง — สแกนเนอร์ที่ดึงจาก NVD/GHSA โดยตรง ทีม DevSecOps จำนวนมากตั้ง gate ไว้ว่า “เจอ Critical ให้ build แดง” ซึ่งแปลว่าใครก็ตามที่ยื่น CVE ปลอมสำเร็จหนึ่งใบ สามารถหยุดสายการ deploy ขององค์กรทั่วโลกได้โดยไม่ต้องแฮ็กอะไรเลย นี่เป็น DoS ต่อกระบวนการพัฒนา ที่มีต้นทุนเท่ากับการกรอกฟอร์ม
ข้อเสนอที่ผมคิดว่าใช้ได้จริงกับทีมขนาดกลางในบ้านเรามีสามข้อ หนึ่ง — แยก policy ระหว่าง “แจ้งเตือน” กับ “หยุด build” ให้ระดับที่หยุด build ต้องมีเงื่อนไขเพิ่มว่าปรากฏบนหน้า advisory ของ upstream เองด้วย ไม่ใช่แค่คะแนน NVD สอง — สำหรับ dependency หลักไม่กี่ตัวที่สำคัญจริง (SQLite, OpenSSL, libxml2) ให้ subscribe หน้า security ของ upstream โดยตรง เพราะโปรเจกต์ระดับนี้ดูแลหน้าตัวเองดีกว่าฟีดกลางอยู่แล้ว สาม — ถ้า advisory ไม่มี PoC ที่รันแล้วเห็นผล ให้ถือว่ายังไม่ยืนยัน ไม่ว่าคะแนนจะ 9.8 แค่ไหน
ท้ายที่สุด เรื่องนี้คือบทเรียนเดียวกับที่เราเขียนถึงซ้ำ ๆ ตลอดปี — ปัญหาไม่ได้อยู่ที่ AI ผลิตของผิด แต่อยู่ที่เราสร้างระบบที่รับของเข้าไปโดยไม่มีใครตรวจ SQLite เป็นหนึ่งในซอฟต์แวร์ที่ผ่านการทดสอบหนักที่สุดในโลก มี test suite ที่ครอบคลุมกว่าโค้ดหลักหลายเท่า ถ้าโปรเจกต์ระดับนี้ยังโดน CVE ปลอมติดหน้า NVD ได้ ไลบรารีที่ทีมไทยใช้อยู่ทุกวันแต่ไม่มีใครเฝ้าจะเหลืออะไร
แหล่งข่าว
อ่านเพิ่มในหมวด งานวิจัย
Anthropic ให้ Claude สร้างชุดข้อมูลที่ดูไร้พิษภัยแต่ทำโมเดลเบี้ยว ซ่อนในเรื่องเลี้ยงผึ้งและมวยปล้ำ จนผ่านระบบตรวจที่คล้ายของจริง
ทีม Alignment ของ Anthropic ให้ Claude ปีนหาชุดข้อมูล fine-tune ที่หลบ monitor ได้ ผลคือซ่อนพฤติกรรมในงานเขียนแนวบทบาทสมมติ และโมเดลที่เทรนแล้วนำไปใช้ในบุคลิกตัวเอง ผลซ้ำได้บน Qwen 3.6 27B แต่การทดลองเอื้อฝ่ายโจมตีมากและไม่ได้สะท้อนโมเดลที่ใช้งานจริง
Memdoor ทำซ้ำ GVS5H ได้: ทีม Qwen3.8-27B ห้าตัวตามทัน Fable 5 บนโจทย์ LiveCodeBench Hard แต่ผู้ทำบอกเองว่า 'เท่า' ไม่ใช่ 'ชนะ'
Memdoor ปล่อย workflow team-solve ที่เขียนวิธี GVS5H เป็น YAML ล้วนและทำคะแนน 9.8/10 บน LiveCodeBench Hard 10 ข้อ เทียบกับ 8.0 ของ Fable 5 แบบเรียกครั้งเดียว แต่ตัวอย่างเล็กและมีข้อจำกัด ส่วนงานวิจัยต้นฉบับชี้ว่าวิธีนี้ไม่ได้ช่วยทุกโมเดล
QwenPU รัน LLM ซ้อนใน LLM ด้วยหน่วยเวกเตอร์ที่คอมไพล์ลงในน้ำหนัก Qwen3.5-4B ส่วน bootgpt ทำให้เครื่อง 386 บูตเข้าโมเดลภาษาโดยไม่มี OS
ผู้สร้าง Qwenputer ปล่อย QwenPU เมื่อ 31 ต.ค. รัน stories260K ของ Karpathy บนหน่วยเวกเตอร์ที่คอมไพล์ลงในน้ำหนัก Qwen3.5-4B ลดเหลือ 53,000 trace token ต่อหนึ่ง token เรื่องเล่า วันเดียวกัน bootgpt ใส่โมเดล int8 ขนาด 11.5KB ให้บูตบนเครื่อง 386 โดยไม่มี OS