Код-ревью Middle SSRF, файлы и редиректы обновлено

Ревью: превью ссылок на Python

Вопрос

Найдите уязвимости в функции, которая строит превью ссылки.

import requests
from flask import request, jsonify

@app.post("/api/preview")
def preview():
    url = request.json["url"]
    if "localhost" in url or "127.0.0.1" in url:
        return jsonify(error="forbidden"), 400
    r = requests.get(url, timeout=30, allow_redirects=True)
    return jsonify(status=r.status_code, body=r.text[:5000])

Коротко

Нужны: проверка схемы, разрешение имени и проверка IP, подключение к проверенному адресу, запрет редиректов, лимиты, а лучше egress-прокси. Пользователю отдавать только нужные поля превью (заголовок, описание), а не сырое тело.

Что должен найти ревьюер

  1. Безопасностьстрока 7
    Чёрный список строк обходится: 127.1, [::1], десятичная запись, домен на 127.0.0.1, приватные сети и 169.254.169.254 вообще не проверяются.
  2. Безопасностьстрока 7
    Не проверяется схема: file:// requests не поддерживает, но другие клиенты и схемы бывают опасны, нужно явно разрешить только http и https.
  3. Безопасностьстрока 9
    allow_redirects=True: внешний сервер перенаправит на внутренний адрес в обход проверки.
  4. Производительностьстрока 9
    Таймаут 30 секунд и нет лимита размера: легко занять воркеры.
  5. Безопасностьстрока 10
    Сырое тело ответа возвращается пользователю: SSRF становится полноценным чтением внутренних сервисов и метаданных.

Разбор

Нужны: проверка схемы, разрешение имени и проверка IP, подключение к проверенному адресу, запрет редиректов, лимиты, а лучше egress-прокси. Пользователю отдавать только нужные поля превью (заголовок, описание), а не сырое тело.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.