FlawOpen

flawopen.com/Ruby YAML/Ruby YAML

Apakah YAML.load aman untuk input yang tidak tepercaya?

CWE-502: Deserialization of Untrusted DataHalaman referensi
Jawaban singkat

Periksa versi Psych yang benar-benar dimuat aplikasi: Psych 4, yang disertakan dalam Ruby 3.1, mengubah YAML.load agar memakai deserialisasi aman secara default. Versi Psych sebelumnya membangun objek secara bebas; Psych juga dapat diperbarui terpisah dari Ruby. YAML.unsafe_load dan Marshal.load mendeserialisasi objek Ruby dan tidak boleh menerima masukan yang tidak tepercaya.

VULNERABLE
# Psych < 4: YAML.load used unsafe
# object construction by default.
YAML.load(params[:config])

# Every Psych version: explicitly unsafe.
YAML.unsafe_load(user_input)
Psych.unsafe_load(user_input)

# Marshal has no restricted safe-load API.
Marshal.load(cookie_value)
FIXED
# Explicit restricted types; keep this list minimal.
require "yaml"
require "date"

data = YAML.safe_load(
  input,
  permitted_classes: [Date],
  permitted_symbols: [],
  aliases: false
)

# For ordinary external data, prefer JSON and
# validate its shape, values, and input size.
data = JSON.parse(input)

Mengapa YAML dapat berbahaya

Tag YAML dapat dipetakan Psych menjadi objek Ruby. Saat pemuatan tidak aman, dokumen bertag dapat meminta konstruksi sebuah kelas dan memberikan nilai untuk status serialisasinya; dampaknya bergantung pada kelas yang tersedia dan perilakunya. Ini menjadi dasar rantai gadget deserialisasi. Gunakan pemuatan aman untuk YAML tidak tepercaya dan validasi data hasilnya secara terpisah. Risiko umum serupa berlaku pada Python pickle, PHP unserialize, dan Ruby Marshal.load.

Rails dan aplikasi lain dapat memuat banyak dependensi, sehingga kelas dan perilaku yang tersedia bagi rantai deserialisasi tidak aman bertambah. Hal ini bergantung pada penerapan tertentu dan bukan sifat semua aplikasi Rails atau dokumen YAML.

Mengapa perubahan versi membingungkan

Psych 4 mengubah YAML.load agar memakai pemuatan aman secara default dan menambahkan unsafe_load untuk perilaku konstruksi objek sebelumnya. Ruby 3.1 menyertakan Psych 4, tetapi aplikasi dapat memilih versi gem Psych lain. Audit dependensi yang benar-benar terpasang dan runtime, bukan hanya versi Ruby. Pemuatan aman dapat menolak kelas khusus aplikasi atau alias; migrasikan dengan daftar izin eksplisit yang minimal, bukan beralih ke unsafe_load.

Jika pembaruan memperkenalkan unsafe_load, anggap itu temuan keamanan bila masukan dapat dipengaruhi dari luar batas deployment tepercaya. Utamakan safe_load dengan daftar minimum permitted_classes; jangan memperluasnya hanya demi menghilangkan kesalahan kompatibilitas.

FAQ

Pertanyaan umum

Apakah YAML.safe_load sepenuhnya aman?

Psych.safe_load membatasi kelas yang dideserialisasi ke daftar yang diizinkan (secara default tipe skalar dan koleksi dasar) serta menolak alias. Namun, fungsi ini tidak memvalidasi struktur, ukuran, atau aturan bisnis aplikasi. Izinkan hanya kelas yang dibutuhkan, batasi ukuran masukan, lalu validasi hasilnya. Beberapa implementasi dan alur kerja YAML pernah mengalami DoS akibat ekspansi alias; CVE-2024-35221 mencatat kasus pada pemrosesan metadata RubyGems. Ini bukan bukti bahwa setiap pemanggilan Psych.safe_load rentan.

Bagaimana jika saya memuat file konfigurasi sendiri?

File di dalam artefak aplikasi tepercaya dengan perlindungan integritas memiliki asal yang berbeda dari unggahan pengguna atau file yang dikendalikan tenant. Untuk konfigurasi internal pun, utamakan safe_load dan izinkan kelas yang diperlukan saja. Gunakan unsafe_load hanya untuk data tetap yang terbukti tepercaya; jangan untuk konten yang dipengaruhi pengguna atau permintaan.

Apakah Marshal dapat diterima?

Risiko Ruby yang terpisah: Marshal.load

Terpisah dari YAML, dokumentasi Ruby menyatakan bahwa Marshal.load dapat membangun kembali hampir semua kelas yang dimuat dalam proses dan dapat menyebabkan eksekusi kode jarak jauh jika datanya tidak tepercaya. Simpan data Marshal di dalam batas kepercayaan; jangan pernah mendeserialisasi byte dari pengguna atau yang dapat dipengaruhi penyerang.

Referensi

Lihat juga Deserialisasi tidak aman: risiko dan mitigasi .NET BinaryFormatter: Risiko dan Migrasi Keamanan ObjectInputStream Java: Cegah Risiko Deserialisasi Newtonsoft.Json TypeNameHandling: konfigurasi aman? PHP unserialize() dan input tak tepercaya Python pickle.load(): risiko data tak tepercaya