flawopen.com/Deserialisasi tidak aman/Keamanan pickle Python
Apakah pickle.load() Python aman untuk data tak tepercaya?
Tidak. Perlakukan pickle seperti program di dalam paket, bukan catatan pasif: pemuatan dapat menjalankan perilaku rekonstruksi sebelum aplikasi memvalidasi objek. Gunakan format khusus data untuk masukan yang melewati batas kepercayaan.
import pickle # Never accept pickle bytes from a request, upload, # shared cache, or other untrusted source. obj = pickle.loads(untrusted_bytes)
import json
def parse_profile(raw: bytes) -> dict[str, str]:
if len(raw) > 65_536:
raise ValueError("Payload too large")
try:
value = json.loads(raw)
except (json.JSONDecodeError, UnicodeDecodeError):
raise ValueError("Invalid JSON") from None
if not isinstance(value, dict) or set(value) - {"display_name", "theme"}:
raise ValueError("Invalid profile")
name = value.get("display_name")
theme = value.get("theme")
if not isinstance(name, str) or len(name) > 80:
raise ValueError("Invalid display name")
if theme not in {"light", "dark"}:
raise ValueError("Invalid theme")
return {"display_name": name, "theme": theme}
- Aliran pickle:
- Urutan byte khusus Python yang menjelaskan rekonstruksi objek, termasuk referensi global dan perilaku rekonstruksi.
- Unpickling:
- Menafsirkan aliran dan membangun kembali graf objek; fungsi dapat dipanggil dalam proses ini.
- Batas kepercayaan:
- Titik tempat pengguna, layanan, unggahan, atau penyimpanan bersama dapat mengendalikan atau mengubah byte.
- CWE-502:
- Deserialisasi data tak tepercaya; dampaknya bergantung pada kemampuan penyerang memasok atau mengubah data yang dimuat.
Byte tak tepercaya mencapai pickle
Unggahan, permintaan, cache, atau artefak dapat membawa data pickle yang dikendalikan atau diubah penyerang ke proses.
Unpickler mencari global
Interpreter memproses instruksi rekonstruksi; find_class() dapat mengimpor dan mengembalikan global bernama, termasuk fungsi.
Pemuatan memicu perilaku
Instruksi dapat memanggil fungsi saat load() atau loads() berjalan, sebelum aplikasi memeriksa objek hasil.
Dampak mengikuti hak proses
Perilaku berjalan dengan izin proses Python. Jaringan, rahasia, akses berkas, dan isolasi menentukan cakupan dampak.
Mengapa pemuatan pickle melewati batas eksekusi kode
Aliran pickle dapat menyebut global dan fungsi rekonstruksi. Saat unpickling, Unpickler.find_class() mencari global termasuk fungsi; opcode dapat memicu rekonstruksi. Langkah berbahayanya adalah pickle.load() atau pickle.loads() itu sendiri, tanpa pemanggilan execute terpisah sesudahnya. Kode berjalan dengan izin proses. Ini perilaku format yang terdokumentasi; jangan gunakan pickle untuk bertukar data tak tepercaya.
Apa yang diperbaiki JSON — dan yang tidak
Dokumentasi Python memperingatkan bahwa pemuatan pickle tak tepercaya atau yang diubah dapat menjalankan kode arbitrer, sedangkan decoding JSON tidak dengan sendirinya membuat jalur eksekusi tersebut. JSON tidak otomatis memvalidasi masukan: batasi ukuran, wajibkan tipe teratas dan field yang diharapkan, validasi nilai dengan skema, serta terapkan otorisasi secara terpisah. Jika sistem lama harus memakai pickle sementara, autentikasi byte yang persis dengan kunci terlindungi sebelum memuat. Tanda tangan hanya membuktikan asal dan integritas berdasarkan asumsi kunci, dan tidak membuat data jahat dari penanda tangan tepercaya menjadi aman. Migrasikan ke format khusus data.
- ✓Hapus
pickle.load()danpickle.loads()dari jalur yang menerima permintaan, unggahan, cache bersama, atau artefak yang asalnya tidak pasti. - ✓Gunakan JSON atau format khusus data; batasi ukuran, validasi skema dan field, rentang nilai, serta otorisasi endpoint.
- ✓Jika alur internal tepercaya sementara masih memakai pickle, verifikasi HMAC atau tanda tangan atas byte yang persis sebelum memuat, lindungi kunci, dan batasi hak proses.
- ✓Cari pemakai pickle dalam kode dan aliran data; tentukan pihak yang dapat menulis atau mengubah setiap sumber, lalu migrasikan atau isolasi penggunaan berisiko.
Pertanyaan umum
Mengganti find_class() dapat mengurangi risiko dengan membatasi global, tetapi membuktikan loader aman untuk semua protokol dan perilaku yang dapat dicapai itu sulit. Untuk byte dari pengguna, pilih format khusus data.
Ya. JSON menghindari eksekusi kode ala pickle saat decoding, tetapi aplikasi tetap harus memvalidasi tipe, field, ukuran, nilai, dan otorisasi. Pisahkan parsing JSON dari aturan bisnis.
Referensi utama
- Dokumentasi Python — peringatan keamanan pickle dan global terbatas
- Dokumentasi Python — decoder JSON
- CWE-502 — Deserialisasi Data Tak Tepercaya