FlawOpen
● CWE-502 / Unsafe Deserialization

Небезопасная десериализация: риски и защита

Как недоверенные данные pickle, Java Serialization и PHP unserialize могут запускать опасное поведение и как их заменить или ограничить.

💡 Простое объяснение (ELI5)

Сериализация похожа на отправку инструкции по сборке модели. Десериализация выполняет эту инструкцию, восстанавливая данные. Некоторые форматы также могут указывать классы или вызывать hooks при восстановлении объектов. Недоверенные инструкции могут запустить непредусмотренное поведение; последствия зависят от формата, runtime, доступных классов и контекста приложения.

Core Concepts & Key Terms

Сериализация / десериализация
Преобразование данных или объектов в формат хранения или передачи с последующим разбором или восстановлением в программе.
Hooks десериализации
Callbacks вроде Python __reduce__, Java readObject или PHP __wakeup / __unserialize, которые могут выполняться при восстановлении объекта.
Gadget chain
Цепочка уже присутствующих библиотечных действий, способная вызвать непредусмотренный эффект. Наличие зависит от приложения и версий библиотек.
Фильтр десериализации
Политика, ограничивающая классы или метрики графа при чтении потока объектов. Она снижает риск, но не делает недоверенный native object stream хорошим форматом.

How Unsafe Deserialization Can Become an Exploit Chain

Step 1

Недоверенные байты доходят до декодера

Cookie, тело API, сообщение очереди или запись содержит данные, контролируемые атакующим.

Step 2

Приложение вызывает native object format

Код передаёт байты декодеру, например Python pickle, Java ObjectInputStream или PHP unserialize().

Step 3

Восстановление запускает поведение формата

В зависимости от формата и доступных классов конструкторы, hooks, autoloading или методы библиотек могут выполниться до проверки приложения.

Step 4

Последствия зависят от доступного поведения

Доступный gadget или hook может вызвать несанкционированные действия; другие входные данные просто отклоняются или расходуют ресурсы. Выполнение кода не происходит автоматически во всех случаях.

Python / Flask: Unsafe Object Loading vs. Primitive JSON Validation

УЯЗВИМЫЙ ШАБЛОН
# VULNERABLE: pickle can execute behavior during unpickling.
from flask import Flask, request
import pickle

app = Flask(__name__)

@app.post("/api/session")
def load_session():
    # Never deserialize attacker-controlled bytes with pickle.
    session = pickle.loads(request.get_data())
    return {"user_id": session.user_id}
БЕЗОПАСНАЯ ПРОВЕРКА
# SAFER: parse JSON primitives, then validate expected shape.
from flask import Flask, abort, request

app = Flask(__name__)
app.config["MAX_CONTENT_LENGTH"] = 16 * 1024

@app.post("/api/session")
def load_session():
    payload = request.get_json()
    if not isinstance(payload, dict):
        abort(400, "Expected a JSON object")

    user_id = payload.get("user_id")
    if type(user_id) is not int or user_id <= 0:
        abort(400, "Invalid user_id")

    # Resolve authorization and session state server-side.
    return {"user_id": user_id}

Контрольный список усиления защиты

Для JSON также нужны ограничения размера и проверка структуры. Для устаревших форматов объектов не полагайтесь только на список разрешённых классов: проверяйте подлинность точных сериализованных байтов до десериализации и защищайте ключи. MAC не шифрует данные и не предотвращает повторную отправку.

← Открыть каталог безопасности Перейти к руководствам по уязвимостям →