FlawOpen

flawopen.com/Deserialisasi tidak aman/Keamanan pickle Python

Apakah pickle.load() Python aman untuk data tak tepercaya?

CWE-502: Deserialisasi Data Tak TepercayaHalaman referensi
Jawaban singkat

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.

BERBAHAYA — byte tak tepercaya dapat memicu kode saat dimuat
import pickle

# Never accept pickle bytes from a request, upload,
# shared cache, or other untrusted source.
obj = pickle.loads(untrusted_bytes)
PILIHAN LEBIH AMAN — parse data lalu validasi skema
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.
Langkah 1

Byte tak tepercaya mencapai pickle

Unggahan, permintaan, cache, atau artefak dapat membawa data pickle yang dikendalikan atau diubah penyerang ke proses.

Langkah 2

Unpickler mencari global

Interpreter memproses instruksi rekonstruksi; find_class() dapat mengimpor dan mengembalikan global bernama, termasuk fungsi.

Langkah 3

Pemuatan memicu perilaku

Instruksi dapat memanggil fungsi saat load() atau loads() berjalan, sebelum aplikasi memeriksa objek hasil.

Langkah 4

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.

Pertanyaan umum

Apakah Unpickler terbatas membuat pickle dari penyerang aman?

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.

Apakah JSON juga harus divalidasi?

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

Lihat juga Deserialisasi tidak aman: risiko dan mitigasi Apakah Ruby YAML.load aman? Versi Psych dan safe_load .NET BinaryFormatter: Risiko dan Migrasi Keamanan ObjectInputStream Java: Cegah Risiko Deserialisasi Newtonsoft.Json TypeNameHandling: konfigurasi aman? PHP unserialize() dan input tak tepercaya