FlawOpen

flawopen.com/Ruby YAML/Ruby YAML

क्या अविश्वसनीय input के साथ YAML.load सुरक्षित है?

CWE-502: Deserialization of Untrusted Dataसंदर्भ पृष्ठ
संक्षिप्त उत्तर

ऐप्लिकेशन में वास्तव में लोड हुए Psych संस्करण की जाँच करें: Ruby 3.1 के साथ आया Psych 4, YAML.load को डिफ़ॉल्ट रूप से सुरक्षित deserialization करने के लिए बदलता है। पुराने Psych संस्करण बिना इस रोक के ऑब्जेक्ट बनाते थे; Psych को Ruby से अलग भी अपडेट किया जा सकता है। YAML.unsafe_load और Marshal.load Ruby ऑब्जेक्ट deserialize करते हैं, इसलिए इन्हें अविश्वसनीय इनपुट न दें।

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)

YAML खतरनाक क्यों हो सकता है

YAML tags को Psych Ruby ऑब्जेक्ट में बदल सकता है। असुरक्षित लोडिंग में tagged दस्तावेज़ किसी class को बनाने और उसके serialized state के लिए मान देने का अनुरोध कर सकता है; असर उपलब्ध classes और उनके व्यवहार पर निर्भर करता है। इसी से deserialization gadget chains बनती हैं। अविश्वसनीय YAML के लिए सुरक्षित loading करें और लौटे डेटा को अलग से validate करें। ऐसा सामान्य जोखिम Python pickle, PHP unserialize और Ruby Marshal.load में भी है।

Rails और अन्य ऐप्लिकेशन कई dependencies लोड कर सकते हैं, जिससे असुरक्षित deserialization chain को उपलब्ध classes और व्यवहार बढ़ते हैं। यह deployment पर निर्भर है; हर Rails ऐप्लिकेशन या YAML दस्तावेज़ में ऐसा नहीं होता।

संस्करण बदलाव से भ्रम क्यों हुआ

Psych 4 ने YAML.load को डिफ़ॉल्ट रूप से सुरक्षित loading के लिए बदला और पुराने object-construction व्यवहार के लिए unsafe_load जोड़ा। Ruby 3.1 में Psych 4 शामिल था, लेकिन ऐप्लिकेशन अलग Psych gem संस्करण चुन सकते हैं। केवल Ruby संस्करण नहीं, resolved dependency और runtime जाँचें। सुरक्षित loading ऐप-विशिष्ट classes या aliases अस्वीकार कर सकती है; unsafe_load पर जाने के बजाय न्यूनतम स्पष्ट allowlist से migrate करें।

अपग्रेड से unsafe_load जुड़ जाए तो, यदि इनपुट भरोसेमंद deployment सीमा से बाहर प्रभावित हो सकता है, इसे सुरक्षा निष्कर्ष मानें। न्यूनतम आवश्यक permitted_classes के साथ safe_load चुनें; compatibility errors छिपाने के लिए सूची न बढ़ाएँ।

FAQ

अक्सर पूछे जाने वाले प्रश्न

क्या YAML.safe_load पूरी तरह सुरक्षित है?

Psych.safe_load deserialize होने वाली classes को अनुमत समूह तक सीमित करता है (डिफ़ॉल्ट में मूल scalar और collection प्रकार) और aliases अस्वीकार करता है। यह ऐप्लिकेशन की data shape, आकार या business नियम validate नहीं करता। केवल आवश्यक classes अनुमति दें, इनपुट आकार सीमित करें और लौटे डेटा को validate करें। कुछ YAML implementations और workflows में alias विस्तार से DoS हुआ है; CVE-2024-35221 RubyGems metadata parsing का एक मामला दर्ज करता है। इसका अर्थ यह नहीं कि हर Psych.safe_load कॉल vulnerable है।

अगर मैं अपनी configuration फ़ाइलें लोड करूँ तो?

विश्वसनीय और integrity-protected application artifact में रखी फ़ाइल का provenance, user upload या tenant-नियंत्रित फ़ाइल से अलग है। आंतरिक configuration के लिए भी safe_load बेहतर है और केवल आवश्यक classes की अनुमति दें। unsafe_load केवल स्थिर, प्रमाणित रूप से विश्वसनीय डेटा के लिए रखें; user या request से प्रभावित सामग्री पर कभी नहीं।

क्या Marshal कभी स्वीकार्य है?

Ruby का एक अलग जोखिम: Marshal.load

YAML से अलग, Ruby documentation बताता है कि Marshal.load process में loaded लगभग किसी भी class को फिर बना सकता है और अविश्वसनीय data से remote code execution हो सकता है। Marshal data को trusted boundary में रखें; user-supplied या attacker-influenced bytes को कभी deserialize न करें।

स्रोत

यह भी देखें असुरक्षित Deserialization: जोखिम और बचाव | flawopen.com .NET BinaryFormatter: जोखिम और माइग्रेशन Java ObjectInputStream सुरक्षा: डीसिरियलाइज़ेशन जोखिम घटाएँ Newtonsoft.Json TypeNameHandling: सुरक्षित सेटिंग PHP unserialize() और अविश्वसनीय इनपुट Python pickle.load(): अविश्वसनीय डेटा का जोखिम