- Calif giao source tree của Ladybird cho Claude.
- Vài giờ sau, một chain use-after-free trong WebAssembly binding chạy được calc.
- Không phải vì Claude biết Ladybird — mà vì nó đã đọc hết JSC và V8.
TL;DR
Trong series MAD Bugs (Month of AI-Discovered Bugs), Calif Global đưa source tree của Ladybird cho Claude. Vài giờ sau, model đã viết xong một chain use-after-free trong WebAssembly binding và pop được calculator. Lỗi nằm ở pointer cache của typed array bị stale sau khi WebAssembly.Memory chia sẻ được grow() hai lần. Điểm đáng sợ: Claude không cần biết Ladybird — nó chỉ cần đã nuốt hết tài liệu khai thác JSC và V8.
Chuyện gì vừa xảy ra
Ngày 2026-04-23, blog Calif đăng writeup cho thấy Claude, được Bruce (operator) giao source tree Ladybird, đã tìm ra và khai thác trọn vẹn một lỗi RCE trong engine JavaScript LibJS của browser này. Toàn bộ quá trình — từ đọc code, xác định bug class, viết primitive addrof/fakeobj, tới chain ra native code execution — mất "a few hours". PoC bao gồm 4 file HTML: bug1-minimal.html, bug1-wasm-shared-uaf-ptrleak.html, bug1-rce-uname.html, và bug1-rce-calc.html.
Điều oái oăm: researcher tsune đã tìm ra đúng bug này vài ngày trước qua GitHub Security Advisory GHSA-w89h-j2xg-c457. Ladybird đã merge fix — nhưng fix không đủ. Bản vá chỉ refresh pointer stale ở lần grow() đầu, bỏ sót việc track các buffer view cũ ở các lần grow tiếp theo. Claude đúng là đã khai thác đúng variant này.
Bên trong cái bug
Root cause, trích nguyên văn: "The TypedArrayBase cell caches a raw m_data" pointer. Khi một shared WebAssembly.Memory được grow(), buffer cũ bị free, pointer cache vẫn trỏ tới vùng nhớ đã giải phóng. Fast-path assembly interpreter dereference pointer đó — dangling — cho đọc/ghi xuyên heap.
| Property | Giá trị |
|---|---|
| Bug class | Use-after-free (WASM typed array binding) |
| Component | LibJS — C++ (chưa được port sang Rust) |
| Trigger | WebAssembly.Memory shared, grow() 2 lần |
| Primitive | addrof / fakeobj → arbitrary R/W → function pointer overwrite |
| Demo | pop calc + gọi uname(2) |
| Thời gian Claude khai thác | vài giờ |
| Trạng thái | Unpatched ở master commit 36e6323d (2026-04-23) |
Ladybird vs Chrome/Safari: 18 năm chênh lệch
Ladybird là browser engine viết lại từ đầu, không mượn code từ ai. Đó là niềm tự hào kỹ thuật — và cũng là gót chân Achilles về security.
| Engine | Mitigation |
|---|---|
| V8 (Chrome) | V8 sandbox, trusted pointers, renderer sandbox |
| JSC (Safari) | Gigacage, Pointer Authentication (PAC), WebContent sandbox |
| LibJS (Ladybird) | Gần như không có — còn đang raw C++ với pointer cache |
Calif tóm gọn rất chính xác: khoảng cách giữa "RCE trong vài giờ" trên Ladybird và "nhiều tháng công việc của một team chuyên sâu cho một renderer compromise vẫn còn bị sandbox" trên Chrome là mười tám năm kỹ thuật bảo mật, lớp này chồng lên lớp kia, mỗi lớp thêm vào vì đúng kiểu exploit của thế hệ trước đã buộc phải có nó.
Tại sao case này đáng chú ý
Điểm không phải "AI tìm ra bug" — điểm là AI không cần biết target. Khai thác browser engine là vấn đề engine-shaped, không phải codebase-shaped. Một model đã nội hóa literature về JSC và V8 đã biết cách tấn công bất kỳ spec-compliant engine nào. Bạn không cần train Claude trên Ladybird; bạn chỉ cần Claude đã đọc Phrack, các writeup P0, và CTF solution của 15 năm qua.
Hệ quả với engine mới: không có chuyện "security by obscurity của codebase mới". Nếu engine của bạn triển khai spec WASM/JS tiêu chuẩn, AI sẽ biết chỗ cần moi. Mitigation phải có từ ngày đầu — không đợi đến khi user thật xuất hiện.
Áp dụng thực tế
- Offensive research: Claude + tài liệu bug-class engine = prototype RCE trong giờ, không phải tuần.
- Defensive engineering: fuzz
Memory.grow()edge case, audit mọi pointer cache trong typed array binding, ship sandbox process-separation trước khi ship release. - Migration strategy: Ladybird đang port sang Rust từ 02/2026. WASM binding nên là ưu tiên cao hơn các module ít dính tới attacker-controlled memory.
- Responsible disclosure của AI: case này cho thấy khi tsune fix không đủ và Claude vẫn khai thác được, quy trình disclosure cần "variant hunting" bắt buộc — không merge fix mà không có model review lại.
Giới hạn & phạm vi ảnh hưởng
Ladybird chưa có bản release chính thức. Người bị ảnh hưởng chỉ là developer và nightly user — nhưng mọi trang malicious đã có thể tạo shared WebAssembly.Memory và gọi grow() hai lần, ngưỡng tấn công cực thấp. Security policy của Ladybird cho phép disclose công khai pre-release bug nếu maintainer đồng ý, nên writeup công khai toàn bộ PoC.
Chưa có CVE assigned ở thời điểm publish. Ladybird sẽ cần tung bản vá thứ hai xử lý biến thể multi-grow.
Điều cần theo dõi
MAD Bugs là campaign tháng 04/2026 của Calif với 10 phát hiện lớn: vim, emacs, FreeBSD kernel RCE (CVE-2026-4747), radare2, Ghidra Server, nginx (CVE-2026-27654), rsync, Samsung TV, jailbreak iPhone, qmail, và giờ là Ladybird. Tất cả đều dùng công thức pair AI frontier + chuyên gia người.
Hai câu hỏi để ngỏ cho cộng đồng: (1) bao lâu nữa chúng ta sẽ thấy "audit engine mới bằng Claude" là checkpoint bắt buộc của mọi browser project? (2) khi model đọc được hết literature công khai, có phải chiến thuật bảo mật sắp phải xoay sang privileged attack-surface reduction thay vì bug-specific mitigation?
Nguồn: blog.calif.io, califio/publications (PoC), MAD Bugs index.
