Memahami model keamanan WebAssembly: isolasi memory per-instance, capability-based WASI tanpa raw syscall, Content Security Policy, plus best practice validasi imports, interop tanpa unsafe, dan pengamanan supply-chain dengan cargo audit

Setelah di episode 15 kalian mengoptimasi ukuran dan performa — pada episode ini kita membahas apa yang membuat WebAssembly unik di antara semua teknologi runtime: model keamanannya. Jika kalian membaca episode 1-15 dengan teliti, kalian sudah melihat benang merahnya — sandbox, linear memory, capability — dan kini saatnya merangkainya menjadi gambaran keamanan yang utuh.
Mengapa topik ini penting? Karena Wasm digunakan untuk menjalankan kode yang tidak dipercaya: plugin dari vendor pihak ketiga, fungsi user, atau modul yang diunduh dari CDN. Keamanan bukan fitur tambahan — ia adalah alasan mengapa Wasm bisa dipercaya menjalankan kode asing di browser, edge, dan server.
Model keamanan inti Wasm ada di memory linear: setiap instance memiliki memory sendiri yang tidak bisa diakses instance lain. Tidak ada pointer global, tidak ada shared state — kecuali yang di-export secara eksplisit (dan diwasm, SharedArrayBuffer punya aturan ketat sendiri).
Konsekuensi keamanannya:
Dua instance dari modul yang sama (bahkan modul yang berbahaya) tidak bisa saling menyentuh memory — fondasi multi-tenant yang aman.
Inilah perbedaan paling fundamental dengan container. Container memakai kernel syscall — mekanisme yang sama dengan host, hanya dibatasi namespace. WASI sama sekali tidak memberi raw syscall; ia hanya menyediakan fungsi abstrak yang mengimplementasikan akses sesuai izin.
wasmtime run --dir ./data --env TOKEN=x app.wasm--dir ./data — modul hanya bisa mengakses subtree ./data, bukan seluruh filesystem.--env TOKEN=x — hanya environment variable ini yang terlihat.Jika modul berbahaya mencoba membuka /etc/passwd, ia tidak menemukan mekanisme untuk melakukannya sama sekali — bukan sekadar ditolak izinnya.
Tip
Anggap WASI seperti "lemari terkunci dengan kunci yang diberikan satu per satu": bukan "ruangan besar yang dibatasi pagar" (container). Prinsip ini memudahkan audit: daftar capability sebuah modul bisa dibaca langsung dari perintah runtime yang menjalankannya.
Di browser, modul Wasm dimuat seperti aset lain — dan harus dikendalikan CSP:
Content-Security-Policy: default-src 'none';
script-src 'self';
wasm-unsafe-eval;
worker-src 'self' blob:;Poin penting:
wasm-unsafe-eval — mengizinkan eksekusi WebAssembly tanpa 'unsafe-eval' penuh (yang melemahkan keamanan script).worker-src blob: — diperlukan jika memuat modul lewat Web Worker (episode 21).'unsafe-inline' tanpa alasan kuat.Modul Wasm hanya bisa melakukan apa yang imports-nya izinkan. Jadi, validasi imports adalah gerbang keamanan:
function safeImports(modul) {
const izinkan = new Set(["env.log", "env.memory"])
const imports = WebAssembly.Module.imports(modul)
for (const imp of imports) {
if (!izinkan.has(`${imp.module}.${imp.name}`)) {
throw new Error(`import tak diizinkan: ${imp.module}.${imp.name}`)
}
}
return {
env: {
log: (n) => console.log(n),
},
}
}Sebelum instansiasi, cek seluruh permintaan imports modul — siapa yang boleh menyediakan apa. Modul yang meminta import mencurigakan harus ditolak.
Rust punya unsafe — dan interop Wasm sering memaksanya. Prinsip keamanannya:
unsafe di satu modul kecil, tidak tersebar.// Bungkus akses raw dalam satu fungsi dengan guard
pub fn baca_byte(mem: &Memory, ptr: u32, len: u32, i: u32) -> u32 {
if i >= len {
return 0 // out-of-bounds: tolak, jangan crash
}
let bytes = unsafe {
mem.view().data_unchecked() // satu-satunya titik unsafe
};
bytes[(ptr + i) as usize] as u32
}Modul yang aman bisa dibangun dari dependency yang rentan. Audit otomatis adalah bagian wajib CI:
cargo install cargo-audit
cargo auditCek tambahan yang direkomendasikan:
cargo deny — kebijakan lisensi + advisory + sumber crate.wasm-opt --strip-debug — pastikan tidak ada info debugging yang bocor.Sebelum menjalankan modul Wasm yang tidak dipercaya di produksi:
--dir, --env, --listen).wasm-unsafe-eval, bukan 'unsafe-eval'.cargo audit + cargo deny di CI.Warning
Sandbox yang kuat tidak menghapus tanggung jawab host: fungsi yang di-import (log, network, file) tetap bisa disalahgunakan. Perlakukan imports seperti API publik — validasi input, batasi ukuran, dan jangan pernah mengekspos kredensial tanpa kontrol.
Pada episode 16 ini, kalian telah memahami model keamanan WebAssembly dan praktik pengamanannya.
Inti yang harus dibawa pulang:
unsafe, jaga satu titik, dan audit supply-chain di CI.Di episode 17 selanjutnya kita akan membahas networking — WASI wasi:http untuk outbound requests, serve HTTP via runtime, interop fetch di Node, serta streaming async WASI 0.3 untuk real-time dan WebTransport eksperimental. Sampai jumpa di episode 17!