flawopen.com/Teardowns/cve-2026-10032-a2ui-agent-button-xss
CVE-2026-10032: XSS pada tombol buatan agen di A2UI
Pada versi terdampak, openUrl di Basic Catalog bawaan meneruskan URL dari agen ke window.open tanpa membatasi skema. Pengguna harus mengeklik Button yang dirender agar dampak pada origin browser dalam advisori terjadi; tingkatkan ke 0.10.2 atau lebih baru.[1]
Bayangkan sebuah kios tempat asisten memasang tombol dan menulis tujuannya pada kartu yang ia berikan. Kios memeriksa apakah kartu berisi alamat, bukan apakah alamat menuju halaman web biasa. Pengunjung tetap harus menekan tombol; tanpa aturan tujuan, browser dapat memperlakukan alamat sebagai instruksi untuk kios. Perbaikan mem-parsing alamat dan hanya menerima HTTP atau HTTPS.[1], [2]
Konsep Kunci & Istilah
A2UI- Protokol dan proyek sumber terbuka untuk UI buatan agen; advisori membahas Basic Catalog pada paket web_core.[1]
Basic Catalog- Kumpulan fungsi bawaan A2UI untuk aksi UI yang dirender; aktif secara default menurut advisori.[1]
Pemetaan kerangka kerja
- Referensi CWE untuk kelemahan yang dijelaskan dalam panduan ini: CWE-79
Analisis Akar Masalah (Root Cause)
Basic Catalog terdampak memperlakukan argumen URL sebagai string untuk dibuka, bukan input navigasi tak tepercaya dengan kebijakan skema. API memeriksa tipe string, tetapi kode rentan tidak membatasi protokol sebelum window.open(args.url, '_blank'). Button.functionCall dari agen dapat membawa nilai ke sink. Pengguna harus mengeklik tombol; advisori A2UI menjelaskan eksekusi skrip pada origin browser aplikasi korban. Perbaikan upstream mem-parsing URL, hanya mengizinkan http: dan https:, lalu membuka URL ternormalisasi dengan noopener,noreferrer. Ini memperbaiki sink tersebut, bukan menjamin semua UI buatan agen aman.[1], [2]
CVE-2026-10032: versi terdampak dan batas aksi
| Kondisi deployment | Yang dipastikan advisori | Tindakan defensif |
|---|---|---|
| @a2ui/web_core 0.9.0, 0.9.1, 0.9.2, 0.10.0, atau 0.10.1 dengan Basic Catalog bawaan. | Advisori A2UI mencantumkan rilis ini sebagai terdampak dan menyatakan Basic Catalog aktif secara default. | Tingkatkan ke 0.10.2 atau lebih baru dan pastikan versi aplikasi yang diterapkan. |
| Pemanggilan fungsi Button berasal dari data A2UI yang dikendalikan agen dan seseorang mengekliknya. | Advisori menjelaskan alur klik ke openUrl dan dampak pada origin browser; ini bukan zero-click. | Perlakukan argumen aksi sebagai tak tepercaya dan validasi pada fungsi pembuka URL. |
| Aplikasi menggunakan renderer React, Lit, atau Angular milik A2UI. | Advisori memasukkan integrasi ini; batas rentannya adalah aksi Basic Catalog bersama di web_core. | Periksa resolusi paket dan perbarui web_core; jangan anggap pengaturan renderer menghapus aksi. |
| Aplikasi menjalankan @a2ui/web_core 0.10.2 atau lebih baru. | Maintainer menyebut 0.10.2 sebagai versi perbaikan: parsing URL, izin HTTP/HTTPS, dan noopener,noreferrer. | Pertahankan tes regresi skema valid/tidak valid dan tinjau pengganti openUrl kustom. |
Alur Serangan Langkah demi Langkah
Agen menyediakan aksi Button
Data UI A2UI dapat mendefinisikan Button dengan pemanggilan fungsi dan argumen. Perlakukan aksi dari agen sebagai input tak tepercaya.[1]
Basic Catalog menyelesaikan openUrl
Basic Catalog menyediakan openUrl; skema meminta string, tetapi kode rentan tidak membatasi skema URL.[1]
Aksi mencapai window.open
Sebelum patch, openUrl meneruskan string ke window.open tanpa memeriksa protokol. Advisori menjelaskan eksekusi skrip pada origin aplikasi korban.[1]
Kode Sumber: Rentan vs Aman
Cuplikan rentan berasal dari implementasi dalam advisori A2UI. PR #1707 mem-parse alamat, hanya mengizinkan HTTP/HTTPS, serta mencegah halaman terbuka mengendalikan halaman asal atau menerima referrer. Tipe dan import proyek dihilangkan; ini bukan berkas lengkap atau proof of concept.[1], [2]
Cuplikan sumber: basic_functions.ts — OpenUrlImplementation
export const OpenUrlImplementation = createFunctionImplementation(OpenUrlApi, args => {
if (args.url && typeof window !== 'undefined' && window.open) {
window.open(args.url, '_blank');
}
});
export const OpenUrlImplementation = createFunctionImplementation(OpenUrlApi, args => {
if (args.url && typeof window !== 'undefined' && window.open) {
const baseHref =
typeof window.location !== 'undefined' && window.location.href
? window.location.href
: undefined;
let url: URL;
try {
url = baseHref ? new URL(args.url, baseHref) : new URL(args.url);
} catch (e: any) {
throw new A2uiExpressionError(`Invalid URL specified: ${args.url}`, 'openUrl', e);
}
// Daftar protokol yang ketat: hanya HTTP dan HTTPS yang diizinkan.
if (url.protocol !== 'https:' && url.protocol !== 'http:') {
throw new A2uiExpressionError(`Unsupported URL scheme: ${url.protocol}`, 'openUrl');
}
// Selalu gunakan noopener dan noreferrer agar halaman yang dibuka tidak dapat mengendalikan jendela asal.
window.open(url.href, '_blank', 'noopener,noreferrer');
}
});
Daftar Periksa Penguatan Sistem Rekayasa
- ✓Tingkatkan semua dependensi langsung dan transitif @a2ui/web_core ke 0.10.2 atau lebih baru; periksa versi di lockfile dan bundle produksi.[1]
- ✓Inventarisasi aplikasi dengan Basic Catalog dan renderer React, Lit, atau Angular; periksa apakah data agen dapat menentukan pemanggilan fungsi Button.[1]
- ✓Validasi URL pada sink navigasi: parse dan selesaikan dahulu, lalu izinkan hanya skema yang disetujui seperti HTTP/HTTPS; jangan mengandalkan prefiks string.[2]
- ✓Buka tujuan eksternal dengan
noopener,noreferrerdan terapkan kebijakan persetujuan produk secara terpisah; kontrol ini menangani risiko berbeda.[2] - ✓Uji resolusi URL HTTP/HTTPS dan relatif serta penolakan URL rusak dan skema non-HTTP(S) sebelum
window.open.[2] - ✓Perlakukan label, tujuan, dan argumen fungsi dari agen sebagai data tak tepercaya; validasi pada sink aksi, jangan menganggap renderer akan membersihkannya.[1], [2]