Разработчики часто предполагают, что встроенные фичи автоматически выполняют очистку или обеспечивают безопасное поведение.
На практике многие из этих фич содержат нестандартные модели поведения, которыми можно злоупотреблять, превращая логические проблемы в уязвимости:
⚫️
os.path.join (built-in): если один из аргументов начинается с /, Python игнорирует предыдущие сегменты путиimport os
payload = "/etc/passwd"
file = os.path.join("/user/uploads/", payload)
with open(file, "r") as f:
print(f.read())
# выведет содержимое “/etc/passwd”
⚫️
pathlib.joinpath (built-in): если какой-либо сегмент является абсолютным путём, он отбрасывает предыдущие части и продолжает работу с абсолютным путёмfrom pathlib import Path
payload = "/etc/passwd"
file = Path("/var/www/html").joinpath("files", payload)
with open(file, "r") as f:
print(f.read())
# выведет содержимое “/etc/passwd”
⚫️
pickle.loads (built-in): pickle.loads() может выполнять произвольные объекты Pythonimport pickle, base64
payload = "gASVHQAAAAAAAACMBXBvc2l4lIwGc3lzdGVtlJOUjAJpZJSFlFKULg=="
# Выполнить код при десериализации (системная команда ”id”)
file = pickle.loads(base64.b64decode(payload))
⚫️
urllib.parse.urljoin (built-in): формирует итоговый URL, объединяя базовый URL с одним или несколькими компонентами URLfrom urllib.parse import urljoin
payload = "http://evil.com/"
print(urljoin("http://example.com/", payload))
# вывод: http://evil.com/
⚫️ Функция load библиотеки PyYAML (внешняя либа):
yaml.load() может выполнять произвольный Python-код, если ты контролируешь YAMLimport yaml
user_data = "!!python/object/apply:print ['pwned']"
result = yaml.load(user_data, Loader=yaml.Loader)
⚫️ Python3 class pollution (built-in): некорректное присвоение атрибутов может позволить изменять структуру классов или объектов
Пост вдохновлен докладом Алекса Брумена "Python Pitfalls: Turning Developer Mistakes into Vulnerabilities" (текстовая версия) 💡





