1. Skenario dan model ancaman
Sebuah layanan analitik menerima stream Arrow IPC dari penyewa (tenant) eksternal dan meneruskannya ke konsumen Python, Rust, dan Java. Penyerang dapat menyusun skema yang tidak konsisten, panjang yang sangat besar, offset di luar batas, sarang rekursif, kamus berbahaya, atau buffer yang melebihi anggaran penerima. Tujuannya adalah mempertahankan throughput batch sambil memastikan kegagalan penguraian hanya memengaruhi permintaan saat ini.
Tentukan batas kepercayaan terlebih dahulu: bita jaringan, metadata IPC, konten buffer, dan skema bisnis tidak tepercaya; penyewa yang terautentikasi tidak otomatis menghasilkan data yang aman. Model keamanan harus mencakup Arrow Columnar Format, C Data Interface, dan IPC daripada hanya mengandalkan setelan bawaan dari binding satu bahasa.
2. Nyatakan asumsi keamanan Arrow
Format kolumnar mendeskripsikan buffer, panjang, offset, bitmap null, kamus, dan tata letak bersarang. Zero-copy mengurangi penyalinan tetapi dapat membiarkan konsumen membaca wilayah memori yang dideskripsikan oleh input eksternal. Implementasi yang aman memvalidasi metadata terhadap buffer aktual sebelum menyerahkan data ke mesin komputasi.
Jangan menyamakan spesifikasi format yang valid dengan input yang tervalidasi. Versi protokol, tipe ekstensi, dan implementasi bahasa memiliki batasan yang berbeda. Tetapkan versi dan kumpulan tipe yang didukung, serta tentukan kebijakan eksplisit untuk bidang (fields) yang tidak dikenal.
3. Validasi skema, panjang, dan offset
Tahap pertama hanya mengurai metadata yang dibatasi dan memeriksa jumlah bidang, kedalaman sarang, tipe data, referensi kamus, dan batas baris batch. Untuk setiap buffer, verifikasi bahwa offset + length tidak dapat meluap (overflow) dan berada dalam alokasi aktual. Untuk string dan daftar dengan panjang variabel, verifikasi offset monotonik yang tetap berada di dalam buffer nilai.
if offset < 0 or length < 0: reject
if offset > buffer_size: reject
if length > buffer_size - offset: reject
if nesting_depth > MAX_DEPTH: rejectGunakan aritmatika yang aman dari overflow, tolak bilangan bulat negatif atau yang terlalu besar di luar nalar serta jumlah null yang tidak kompatibel dengan skema. Jangan pernah mengalokasikan panjang yang dideklarasikan penyerang sebelum validasi.
4. Terapkan anggaran sumber daya dan backpressure
Tetapkan anggaran per permintaan untuk bita metadata, kolom, baris, total bita buffer, kedalaman sarang, ukuran kamus, dan waktu CPU. Teruskan anggaran ke setiap parser batch; batalkan permintaan dan segera lepaskan alokasi saat anggaran terlampaui.
Gunakan pembacaan terbatas dan backpressure batch untuk stream IPC alih-alih memuat seluruh unggahan ke dalam memori sekaligus. Batasi ekspansi dari kompresi, kamus, dan referensi berulang sehingga input kecil tidak dapat menjadi alokasi yang besar. Isolasi kuota per penyewa sehingga satu permintaan berbahaya tidak dapat menghabiskan semua worker.
5. Putuskan kapan mempertahankan zero-copy dan kapan harus menyalin
Pertahankan zero-copy hanya-baca hanya setelah membuktikan kepemilikan buffer, masa pakai (lifetime), dan batas-batasnya, serta mengonfirmasi bahwa kode downstream tidak dapat mengubahnya (mutate). Buffer penerimaan jaringan, mmap sementara, atau memori FFI lintas bahasa yang mungkin dilepaskan, digunakan kembali, atau ditulisi harus disalin ke arena terkontrol.
Menyalin bukanlah sebuah kegagalan; ini adalah batas keamanan yang mengubah masa pakai yang tidak tepercaya menjadi masa pakai yang terkontrol. Pilih per kolom: bagikan buffer numerik yang tervalidasi, dan salin string, kamus, atau kolom bersarang jika anggaran memungkinkan. Catat bita yang disalin dan latensi alih-alih menyembunyikan risiko di balik "full zero-copy".
6. Isolasi penguraian, kesalahan, dan kompatibilitas
Jalankan parser dalam worker atau proses terbatas dengan batasan CPU, memori, deskriptor file, dan wall-time. Kembalikan alasan terstruktur seperti versi tidak didukung, ketidakcocokan skema, offset di luar batas, atau anggaran terlampaui; jangan pernah menggemakan payload mentah atau alamat internal.
Gunakan daftar izin (allowlists) untuk tipe ekstensi, metadata yang tidak dikenal, dan bidang masa depan. Untuk kompatibilitas, konversikan ke skema internal sebelum memasuki mesin kueri. Sebelum meningkatkan Arrow 25 atau binding bahasa, jalankan korpus berbahaya yang sama sebagai uji diferensial dan bandingkan kelas kesalahan, memori puncak, dan hasil.
7. Amati, lakukan fuzzing, dan tanggapi insiden
Catat penyewa, versi format, hash skema, alasan penolakan, ukuran input, durasi penguraian, memori puncak, bita yang disalin, dan pembatalan; buat hash dari payload alih-alih mencatat konten sensitif ke log. Berikan peringatan pada setiap kelas penolakan dan bedakan klien yang salah konfigurasi dari serangan yang berkelanjutan.
Lakukan fuzzing pada skema acak, offset, bitmap null, kamus, dan stream yang terpotong, menggunakan AddressSanitizer, MemorySanitizer, atau alat yang setara untuk mendeteksi crash dan akses di luar batas. Simpan reproduksi minimal dan uji regresi setelah perbaikan. Untuk anomali produksi, isolasi penyewa atau versi format terlebih dahulu, lalu analisis sampel dan putar (rotate) kredensial yang terpengaruh.
8. Rubrik dan tindak lanjut
Harus dijelaskan
- Memperlakukan metadata, buffer, dan skema bisnis Arrow sebagai tidak tepercaya; memvalidasi panjang, offset, kedalaman, dan referensi kamus.
- Mengontrol memori dan CPU dengan anggaran, backpressure, dan isolasi alih-alih memperlakukan zero-copy sebagai tujuan mutlak tanpa syarat.
- Menyediakan batas penyalinan, kesalahan terstruktur, fuzzing, observabilitas, dan strategi peningkatan versi.
Pertanyaan tindak lanjut
- Kolom string memiliki offset monotonik, tetapi nilai akhir melebihi buffer. Pada lapisan mana Anda menolaknya?
- Bagaimana Anda mencegah kamus atau daftar bersarang berkembang menjadi biaya sumber daya yang tak terbatas?
- Bagaimana Anda membuktikan bahwa binding Python, Rust, dan Java mencapai kesimpulan yang sama untuk satu input berbahaya?
Panduan penilaian
Jawaban yang sangat baik menghubungkan validasi format, tata kelola sumber daya, kepemilikan memori, dan bukti runtime: menolak tata letak yang mustahil, mengonsumsi batch dalam batas anggaran, dan membuktikan dengan isolasi, fuzzing, dan metrik bahwa input yang tidak tepercaya tidak dapat menjadi kegagalan di seluruh layanan.