FlawOpen

flawopen.com/असुरक्षित deserialization/PHP unserialize()

क्या PHP unserialize() अविश्वसनीय input के लिए सुरक्षित है?

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

allowed_classes सेट होने पर भी अविश्वसनीय input को unserialize() में न दें। PHP objects बहाल कर सकता है और __unserialize() या __wakeup() चला सकता है; हमलावर ऐप या autoloader में उपलब्ध classes का दुरुपयोग कर सकता है। अविश्वसनीय डेटा के लिए JSON उपयोग करें। Associative decoding में JSON objects arrays बनते हैं और magic-method व्यवहार वाली application classes instantiate नहीं करते।

असुरक्षित
<?php
// Cookie content is controlled by the client.
$input = $_COOKIE['prefs'] ?? '';
$data = unserialize($input);

// Restoring an object may invoke its
// __unserialize() or __wakeup() method.
// Later object destruction may invoke __destruct().

// The risk depends on available classes,
// their serialized state, and reachable behavior.
ठीक किया गया
<?php
$input = $_POST['prefs'] ?? null;
if (!is_string($input)) {
    http_response_code(400);
    exit;
}

try {
    $data = json_decode(
        $input,
        true,
        512,
        JSON_THROW_ON_ERROR
    );
} catch (JsonException $e) {
    http_response_code(400);
    exit;
}

if (!is_array($data)) {
    http_response_code(400);
    exit;
}

// Validate required keys and value types here.

PHP object-injection chain के लिए क्या आवश्यक है

Object injection का अर्थ अपने-आप code execution नहीं है। Serialized value में ऐसा class होना चाहिए जिसे PHP resolve कर सके और विकल्प अनुमति दें; restoration या बाद का उपयोग भी सुरक्षा-प्रभाव वाले व्यवहार तक पहुँचना चाहिए। Object बहाल करते समय PHP __unserialize() या __wakeup() चला सकता है; नष्ट होने पर __destruct() और string context में उपयोग पर __toString() चल सकता है।

Property-Oriented Programming (POP) chain ऐप या लोड की गई dependencies में पहले से मौजूद व्यवहार को जोड़ती है। Exploitability वास्तविक classes, serialized properties, call path और runtime शर्तों पर निर्भर है। लक्ष्य के लिए gadget chain साबित करनी होगी; केवल unserialize() की मौजूदगी पर्याप्त प्रमाण नहीं।

String filtering और allowed_classes पूरा समाधान क्यों नहीं हैं

O: जैसे marker रोकना, class नाम filter करना या string की लंबाई सीमित करना PHP serialization को सुरक्षित रूप से validate नहीं करता। PHP स्पष्ट रूप से चेतावनी देता है कि allowed_classes की परवाह किए बिना अविश्वसनीय input को unserialize() में न दें। निषिद्ध class का object __PHP_Incomplete_Class बनता है, पर संरचना फिर भी parse होती है। विश्वसनीय legacy data में परिणाम का आकार validate करें और गहराई सीमित करें। Client state के लिए JSON चुनें।

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

क्या allowed_classes => false अविश्वसनीय input को सुरक्षित बनाता है?

नहीं। यह सामान्य application classes की restoration रोकता है; निषिद्ध objects __PHP_Incomplete_Class बनते हैं। PHP फिर भी इस विकल्प के बावजूद अविश्वसनीय input को unserialize() में देने से मना करता है। इसे केवल विश्वसनीय legacy data के लिए defense-in-depth मानें, परिणाम validate करें और max_depth सीमित रखें। PHP मैनुअल के अनुसार यह विकल्प enumerations को प्रभावित नहीं करता।

क्या HMAC serialized data को सुरक्षित करता है?

यदि कुंजी गुप्त रहे और ऐप द्वारा बनाए गए डेटा की signature को deserialize करने से पहले hash_equals() से जाँचा जाए, तो HMAC integrity प्रमाणित कर सकता है। Parsing से पहले गलत signature अस्वीकार करें। HMAC encryption नहीं है और replay नहीं रोकता; freshness चाहिए तो expiry या nonce जोड़ें। मनमाने user data को विश्वसनीय बनाने के लिए sign न करें।

क्या यह Python pickle या Java ObjectInputStream जैसा ही जोखिम है?

तीनों में serialized data से objects बहाल करने का व्यापक जोखिम है, लेकिन formats, hooks, class resolution और बचाव अलग हैं। हर runtime और उपलब्ध classes का अलग मूल्यांकन करें; एक platform की gadget chain दूसरे पर लागू मानकर न चलें।

संदर्भ

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