Валидация входных данных и инъекции
Каждое значение, пришедшее извне: поле формы, query string, заголовок, загруженный файл, URL, который ты запрашиваешь, - враждебно, пока не доказано обратное. Инъекция происходит, когда это значение трактуется как код или структура, а не как данные.
Чек-лист
- Всегда используй параметризованные запросы. Никогда не собирай SQL конкатенацией строк. Используй связанные параметры или ORM, который связывает их за тебя. Это закрывает SQL-инъекции. То же правило относится к NoSQL и к shell-командам.
- Экранируй вывод по контексту. Полагайся на шаблонизатор или UI-фреймворк, который экранирует по умолчанию (например, React). Будь очень осторожен с любым "выводом сырого HTML". Именно через него в приложение попадает межсайтовый скриптинг (XSS).
- Проверяй по allowlist, а не по denylist. Определи, как выглядит валидное значение, и отклоняй всё остальное, вместо того чтобы пытаться заблокировать плохой ввод.
- Защищай серверные запросы (SSRF). Если сервер запрашивает URL, переданный пользователем, проверь его и блокируй внутренние диапазоны и адрес метаданных облака (169.254.169.254). Используй строгую проверку хоста и закрепляй DNS, чтобы противодействовать DNS rebinding.
- Никогда не десериализуй недоверенные данные в код. Избегай pickle, нативной десериализации Java или PHP и подобного для байтов, контролируемых атакующим. Они выполняют код.
- Укрепляй загрузку файлов. Проверяй реальное содержимое (magic bytes), а не только расширение или заявленный тип. Задай жёсткий лимит размера. Храни файлы вне веб-корня, под случайным или id-based именем, никогда под именем файла, которое дал пользователь. Отдавай их с правильным content type и
X-Content-Type-Options: nosniff. По возможности проверяй на вредоносное ПО. - Валидируй тела запросов по схеме. Отклоняй неизвестные поля, а не пропускай их (см. mass assignment в API и запросах).
Как тестировать
- Отправь
' OR 1=1 --,<script>alert(1)</script>и${7*7}в каждое поле и убедись, что они сохраняются и показываются как литеральный текст. - Направь любой URL-ввод на
http://169.254.169.254/и наhttp://localhost/. - Загрузи HTML-файл, переименованный в
.png, и убедись, что он отклонён или отдан безвредно.