Как защитить загрузку по URL от SSRF
Вопрос
Пользователь указывает URL картинки, и сервер её скачивает. Как вы защитите эту функцию?
Попробуйте сами
Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.
Показать ответ и разбор
Коротко
Что должно прозвучать в ответе
Только схемы http и https, лимит размера, таймауты
Резолв DNS и запрет приватных, loopback, link-local и служебных адресов
Проверка на каждом редиректе или запрет редиректов
Защита от DNS rebinding: подключаться к уже проверенному IP
Изолированный исходящий прокси или отдельный сервис без доступа к внутренней сети
Проверка содержимого: тип, размеры, перекодирование
Что могут спросить следом
- Что такое DNS rebinding?
- Почему недостаточно проверить строку URL регулярным выражением?
Разбор
Образцовый ответ: «Главная угроза тут SSRF: сервер внутри сети и может обратиться к метаданным облака, внутренним API, Redis. Поэтому, во-первых, разрешаю только http и https и, если возможно, белый список доменов. Во-вторых, сам резолвлю имя и проверяю все полученные IP: никаких приватных диапазонов, loopback, link-local вроде 169.254.169.254, адресов IPv6 этих категорий. Проверка строки регулярным выражением не работает: есть десятичная запись IP, IPv6, домены, которые резолвятся во внутренние адреса. В-третьих, подключаюсь именно к проверенному IP, иначе DNS rebinding: при повторном резолве имя укажет уже на внутренний адрес. Редиректы либо запрещаю, либо проверяю каждый шаг так же. Ставлю таймауты и лимит размера ответа, чтобы не повиснуть на бесконечном потоке. Самый надёжный слой это инфраструктура: скачивание идёт через отдельный прокси или воркер в сети без доступа к внутренним ресурсам. И само содержимое проверяю: тип по сигнатуре, размеры, перекодирую картинку».
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.
Предыдущий вопрос
Безопасность Python-бэкенда: что вы проверяете
Следующий вопрос
Как защититься от SQL-инъекции