SQL Injection, XSS и CSRF часто упоминают рядом, но это разные механизмы. При SQL Injection данные вмешиваются в структуру SQL-запроса. При XSS недоверенное содержимое становится исполняемым кодом в браузере. При CSRF браузер отправляет нежелательное действие с автоматически приложенными credentials пользователя.
Для QA важно различать место ошибки и ожидаемую защиту. Одинаковая строка во всех полях и отсутствие заметной ошибки не доказывают безопасность. Работай на согласованном стенде, с тестовыми аккаунтами и минимальными безопасными примерами, которые проверяют конкретную гипотезу.
SQL Injection: данные становятся частью запроса
Риск появляется, когда SQL собирают с небезопасным включением недоверенного ввода. Источником может быть поиск, фильтр, параметр сортировки, импорт или ранее сохранённое значение. Проверять только форму логина недостаточно.
Основная защита для значений — параметризованные запросы. Ввод передаётся как данные отдельно от структуры SQL. Для имён колонок и направления сортировки, где параметры запроса обычно неприменимы, нужен контролируемый выбор из разрешённых значений. ORM сам по себе не гарантирует безопасность: raw SQL с конкатенацией сохраняет риск. Права аккаунта базы должны соответствовать необходимым операциям.
Как проверять SQL-обработку без ложных выводов
Начни с нормальных данных, содержащих апострофы и другие допустимые символы: например, фамилии O'Connor. Корректная система должна сохранять и находить такую запись согласно требованиям без ошибки SQL и изменения области поиска. Нельзя автоматически считать запрет всех апострофов хорошей защитой: он может ломать легитимные данные.
Дальше вместе с разработчиком проверь путь параметра до запроса и наличие параметризации. Один успешный пример подтверждает только своё поведение, а не отсутствие всех SQL-инъекций. При подозрении фиксируй запрос, ошибку и тестовый набор; расширенную проверку проводи согласованными методами без извлечения чужих данных.
XSS: важно место использования данных
Пользовательский текст может отображаться сразу после отправки, после сохранения или через клиентский DOM. Это разные пути, которые полезно проверять отдельно. Один комментарий иногда появляется в карточке, поиске, уведомлении и административной панели; безопасное отображение в первом месте ничего не доказывает об остальных.
Защита зависит от контекста: HTML-текст, атрибут, URL и JavaScript требуют разных правил. Автоматическое экранирование шаблонов полезно, но опасные API и обходы защиты могут вернуть риск. Если продукт разрешает ограниченный HTML, нужен подходящий sanitizer с разрешёнными конструкциями. CSP добавляет защитный слой, но не заменяет правильную обработку вывода.
Как проверить отображение маркера
Используй уникальную безопасную строку, например QA <marker> & «проверка», в поле обычного текстового комментария. Сохрани её, открой запись снова под другим тестовым пользователем и проверь все предусмотренные представления. В интерфейсе строка должна оставаться текстом; её части не должны неожиданно превращаться в DOM-элементы или менять структуру страницы.
Сверяй rendered DOM и путь данных, а не только внешний вид. Пропавшая часть строки может означать ошибку отображения, но не обязательно доказывает XSS. Подтверждение исполнения, если оно нужно, проводится отдельным согласованным безвредным тестом и не должно затрагивать реальные сессии или внешние системы.
CSRF: нежелательное действие от имени пользователя
CSRF актуален, когда браузер автоматически отправляет credentials, например session cookie, а сервер не отличает ожидаемое действие от навязанного. Пользователь может быть корректно аутентифицирован; проблема заключается в происхождении и подтверждении запроса.
Типовая защита включает предусмотренный механизм CSRF-токена, проверку Origin/Referer и настройки SameSite как дополнительный слой. Конкретная схема зависит от архитектуры. Cross-site и cross-origin — разные понятия, поэтому доверенный соседний поддомен требует отдельного анализа. POST сам по себе не защищает, а HttpOnly решает другую задачу. Одна настройка CORS тоже не блокирует все способы отправки межсайтового запроса.
Как проверить защиту изменения состояния
Возьми изменение некритичной настройки тестового аккаунта. Сначала выполни разрешённый запрос и запиши результат. Затем проверь отсутствие, повреждение и неверную привязку CSRF-токена, если выбранная схема его требует. Дополнительно воспроизведи запрос из контролируемого чужого origin, сохраняя предусмотренные браузерные условия.
Смотри не только ответ: после отвергнутого запроса настройка не должна измениться. Проверяй, что GET не выполняет изменение состояния, а альтернативный endpoint или формат тела не обходит защиту. Для API с другим способом передачи credentials модель риска может отличаться; отсутствие CSRF-токена само по себе ещё не является доказательством уязвимости.
Практический пример: профиль пользователя
В тестовом профиле есть фамилия, публичное описание и настройка языка. Создай начальные значения и сохрани снимок ожидаемого состояния.
- →Сохрани O'Connor: фамилия записана полностью, поиск находит нужную запись, ответ не раскрывает SQL-диагностику.
- →Сохрани безопасный текстовый маркер в описании: он одинаково безопасно отображается в профиле, списке и административном представлении.
- →Выполни изменение языка с нарушением принятой CSRF-защиты: сервер отклоняет операцию, язык после повторного чтения остаётся прежним.
- →Повтори корректные действия: защита не блокирует легитимное редактирование и сохраняет ожидаемые значения.
Это минимальный регресс конкретных защитных механизмов. Измеримый итог — три ожидаемых результата по данным и отсутствие побочного изменения при запрете. Он не заменяет отдельное исследование всех точек ввода и использования данных.
Типичные ошибки и ретест
Не объединяй эти классы одной формулировкой «не валидируется ввод». SQLi требует разделения кода и данных на сервере, XSS — безопасного использования в контексте браузера, CSRF — защиты действия с учётом credentials и происхождения запроса. Клиентская валидация не заменяет ни одну из этих границ.
После исправления проверь соседние поля, повторное чтение, импортированные данные и другие endpoints того же действия. Сохрани разрешённый сценарий рядом с запрещённым: безопасность должна предотвращать нежелательное поведение и одновременно сохранять нормальную работу пользователя.
Что должен вынести QA из этой темы
Сначала определи механизм и границу доверия, затем выбери безопасную проверку и наблюдай фактическое состояние. Не считай отсутствие ошибки доказательством защиты. Самый полезный отчёт показывает конкретный путь данных или действия, ожидаемый контроль и воспроизводимый результат на тестовом наборе.