Перейти к содержимому

Вопросы по безопасности веб-приложений на собеседовании: что спрашивают и как отвечать

Команда Interview Assistantтехнические вопросыбезопасность

На собеседовании по безопасности веб-приложений проверяют не умение взламывать, а понимание, откуда берётся уязвимость и какой принцип её закрывает: SQL-инъекция возникает, когда данные пользователя смешиваются с кодом запроса; XSS — когда они попадают в страницу как разметка; CSRF — когда браузер сам прикладывает сессионные куки к чужому запросу. Сильный ответ называет причину, показывает атаку одной фразой и сразу даёт защиту: параметризованные запросы, экранирование вывода, CSRF-токены и атрибут SameSite, хеширование паролей специальными алгоритмами. Ниже разобраны главные темы, ответы на двух уровнях глубины и ловушки, на которых кандидаты теряют баллы.

Что на самом деле проверяет интервьюер

Вопросы по безопасности редко нужны, чтобы услышать определения. Обычно за ними стоят три проверки:

  • Привычка думать о злоумышленнике. Видите ли вы в каждом входном параметре потенциально враждебные данные, а не только то, что присылает ваш фронтенд.
  • Понимание причин, а не рецептов. Кандидат, который знает «надо экранировать», но не может объяснить, куда и зачем, звучит слабее того, кто объясняет принцип.
  • Эшелонированная защита. Одной меры недостаточно: параметризация не отменяет прав на уровне БД, а CSRF-токен не заменяет проверку авторизации.

Общую структуру такого интервью можно посмотреть в статье про вопросы на техническом собеседовании.

OWASP Top 10 на уровне идей

OWASP Top 10 — публикуемый перечень самых распространённых категорий рисков для веб-приложений. Список обновляется, и заучивать номера пунктов не нужно. Достаточно знать крупные группы и уметь привести пример для каждой:

ГруппаИдея в одной фразеПример
Нарушение контроля доступаПользователь делает то, что ему не разрешеноПодстановка чужого id в URL
Криптографические ошибкиДанные не защищены или защищены слабоПароли в открытом виде, HTTP вместо HTTPS
ИнъекцииДанные интерпретируются как командыSQL-инъекция, XSS
Небезопасный дизайнУязвимость заложена в логикеСброс пароля по предсказуемой ссылке
Неверная конфигурацияНебезопасные настройкиАдминка без пароля, включённая отладка в проде
Уязвимые компонентыИзвестные дыры в зависимостяхДавно не обновлявшаяся библиотека
Ошибки аутентификацииСлабый вход и управление сессиямиНет ограничения на число попыток
Недостаточный журнал и мониторингАтаку нельзя заметитьНет логов неудачных входов

Если вас просят назвать «главное», уместно сказать, что контроль доступа и инъекции остаются типичными источниками проблем, и тут же привести пример.

SQL-инъекции

Коротко: SQL-инъекция — это когда ввод пользователя становится частью текста запроса и меняет его смысл. Защита — параметризованные запросы.

Развёрнуто. Уязвимый код склеивает строку:

# Плохо: ввод попадает в текст запроса
query = f"SELECT * FROM users WHERE email = '{email}'"
cursor.execute(query)

Если email содержит кавычку и фрагмент SQL, структура запроса меняется. Правильно передавать значения отдельно от текста запроса:

# Хорошо: драйвер передаёт значение как данные, а не как код
cursor.execute("SELECT * FROM users WHERE email = %s", (email,))

Параметризация работает, потому что запрос и данные идут разными путями, и база не пытается разбирать данные как SQL. Важные оговорки:

  • Параметризовать можно значения, но не имена таблиц и колонок. Для динамической сортировки используйте белый список допустимых полей.
  • ORM защищает от инъекций, пока вы не собираете сырой SQL конкатенацией.
  • Дополнительный слой — минимальные права учётной записи приложения в базе. Подробнее про запросы и индексы — в статье про вопросы по SQL на собеседовании.

XSS: межсайтовый скриптинг

Коротко: XSS — это когда чужой JavaScript выполняется на вашей странице в контексте вашего домена. Защита — экранировать вывод в зависимости от контекста и ограничивать выполнение скриптов политикой CSP.

Развёрнуто. Принято различать три вида:

  • Хранимая (stored): вредоносный текст сохранён в базе, например в комментарии, и отдаётся всем посетителям.
  • Отражённая (reflected): значение из запроса сразу попадает в ответ, и жертве нужно перейти по подготовленной ссылке.
  • DOM-based: уязвимость целиком на клиенте, когда скрипт пишет данные в страницу небезопасным способом, например через innerHTML.

Что отвечать про защиту:

  1. Экранировать данные при выводе. Контекст важен: в тексте HTML, в атрибуте, в JavaScript и в URL правила разные. Современные шаблонизаторы и фреймворки экранируют по умолчанию, и опасны именно места, где это отключают вручную.
  2. Не вставлять пользовательский ввод через innerHTML, а использовать textContent либо проверенный санитайзер для разрешённой разметки.
  3. Включить Content-Security-Policy, чтобы ограничить источники скриптов. Это второй рубеж, а не замена экранированию.
  4. Ставить кукам флаг HttpOnly, чтобы скрипт не мог прочитать сессионный идентификатор. Сам XSS это не закрывает, но уменьшает ущерб.

CSRF: подделка межсайтового запроса

Коротко: CSRF — это когда вредоносная страница заставляет браузер жертвы отправить запрос на ваш сайт, а браузер сам прикладывает куки. Защита — CSRF-токены и атрибут SameSite у кук.

Развёрнуто. Атака возможна, потому что аутентификация держится на куках, которые браузер отправляет автоматически. Основные меры:

  • CSRF-токен: случайное значение, привязанное к сессии и проверяемое на каждом изменяющем запросе. Чужой сайт его не знает.
  • SameSite=Lax или Strict: браузер не прикладывает куку к большинству межсайтовых запросов.
  • Безопасные методы: GET не должен менять состояние.
  • Проверка заголовков Origin и Referer как дополнительный слой.

Полезно отличать CSRF от XSS: CSRF использует доверие сайта к браузеру жертвы, XSS — доверие браузера к сайту. Если на странице есть XSS, CSRF-токены, как правило, не спасают, потому что скрипт может прочитать токен.

Аутентификация и сессии

Аутентификация отвечает на вопрос «кто это», авторизация — «что ему можно». Путаница между ними — частая ошибка в ответах.

Типовые вопросы и сильные формулировки:

ВопросСлабый ответСильный ответ
Как устроена сессия?«Хранится в куке»Сервер выдаёт случайный идентификатор, хранит состояние у себя, кука с флагами HttpOnly, Secure, SameSite; после входа идентификатор меняется
Сессия или JWT?«JWT современнее»Сессии легко отозвать, но нужно общее хранилище; JWT не требует хранилища на проверку, но сложно отзывается, поэтому нужен короткий срок жизни и refresh-механизм
Где хранить токен в браузере?«В localStorage»localStorage доступен скриптам, значит уязвим при XSS; кука с HttpOnly скрывает токен от JavaScript, но требует защиты от CSRF
Как защитить вход?«Сложный пароль»Ограничение числа попыток, многофакторная аутентификация, одинаковые сообщения об ошибке для неверного логина и пароля

Отдельно стоит знать про авторизацию: проверять права нужно на сервере для каждого объекта, а не только скрывать кнопки в интерфейсе. Подстановка чужого идентификатора в запрос — одна из самых частых реальных уязвимостей.

Хранение паролей

Коротко: пароли хранят не в открытом виде и не как обычный хеш, а как результат специальной медленной функции с солью.

Развёрнуто:

  • Универсальные быстрые хеши вроде SHA-256 для паролей не подходят: перебор по ним слишком дешёв.
  • Используют алгоритмы, созданные для паролей: bcrypt, scrypt, Argon2. Их стоимость настраивается, и её можно повышать со временем.
  • Соль — уникальное случайное значение для каждого пользователя. Она не позволяет применять заранее подготовленные таблицы и скрывает одинаковые пароли. Хорошие библиотеки генерируют и хранят соль сами.
  • Шифрование для паролей не нужно: пароль не требуется восстанавливать, достаточно проверять.
  • При утечке базы цель — сделать массовый подбор как можно более дорогим.

Секреты и конфигурация

Ключи API, пароли от баз и подписывающие ключи не должны попадать в репозиторий, образы и логи. Типовой сильный ответ включает:

  • хранение секретов в переменных окружения или специализированном хранилище, а не в коде;
  • разные секреты для разных окружений и минимальные права у каждого;
  • возможность ротации: если ключ утёк, его можно заменить без переписывания кода;
  • понимание, что удаление секрета из последнего коммита не убирает его из истории репозитория, поэтому утёкший ключ считают скомпрометированным и перевыпускают.

Типичные ошибки и ловушки

  • Перечислять атаки без защиты. Интервьюеру важнее услышать, как вы это закроете.
  • Предлагать «валидацию ввода» как единственную меру. Валидация полезна, но от инъекций защищает параметризация, от XSS — экранирование вывода.
  • Утверждать «у нас HTTPS, значит безопасно». HTTPS защищает канал, но не от инъекций, XSS и ошибок доступа. Как устроен защищённый канал, показано в разборе вопроса «что происходит, когда вводишь URL в браузере».
  • Смешивать шифрование, хеширование и кодирование. Base64 — это кодирование, а не защита.
  • Игнорировать авторизацию на уровне объектов.
  • Говорить абсолютами. «Это полностью исключает атаку» звучит наивно; честнее сказать «сильно снижает риск».

Вопросы о безопасности часто всплывают и при проектировании: как защитить API, где проходят границы доверия. Эти темы стоит держать в голове на интервью по system design, а влияние распределённой архитектуры на поверхность атаки разобрано в статье про микросервисы и монолит.

Чек-лист подготовки

  • Могу объяснить SQL-инъекцию, XSS и CSRF по схеме «причина — пример атаки — защита».
  • Знаю разницу между аутентификацией и авторизацией и могу привести пример ошибки доступа.
  • Могу сравнить сессии и JWT и назвать плюсы и минусы каждого.
  • Могу объяснить, почему пароли хранят через bcrypt, scrypt или Argon2 с солью.
  • Знаю, где хранить секреты и что делать, если ключ утёк.
  • Знаю флаги кук: HttpOnly, Secure, SameSite.
  • Могу рассказать о реальном случае из практики: найденной проблеме, ревью, обновлении зависимости.
  • Не обещаю абсолютной защиты и говорю про снижение риска.

Где здесь помогает Interview Assistant

Вопросы по безопасности часто звучат неожиданно: «как бы вы защитили эту форму» или «что не так с этим кодом». Interview Assistant — приложение для macOS и Windows, которое транскрибирует речь интервьюера в реальном времени и отвечает сначала краткими тезисами, а затем развёрнутым разбором с подводными камнями: например, напомнит, что от XSS защищает экранирование вывода, а не только валидация. Ассистент не заменяет знания и собственный опыт, но помогает не потерять нить под волнением. Первые 20 минут бесплатны — можно заранее проверить, как приложение слышит ваш звонок.

Частые вопросы

Нужно ли знать весь список OWASP Top 10 наизусть?

Нет, номера пунктов запоминать не нужно. Достаточно знать основные группы рисков, уметь привести пример для каждой и помнить, что список периодически обновляется.

Чем XSS отличается от CSRF?

При XSS чужой скрипт выполняется на вашей странице и может читать данные и действовать от имени пользователя. При CSRF скрипта на вашей странице нет: вредоносный сайт лишь заставляет браузер отправить запрос с автоматически приложенными куками.

Достаточно ли ORM, чтобы не бояться SQL-инъекций?

ORM защищает, пока значения передаются как параметры. Опасность возвращается, когда в сыром SQL или в динамических именах полей используется конкатенация строк с пользовательским вводом.

Где безопаснее хранить токен: в localStorage или в куке?

Универсального ответа нет. localStorage доступен любому скрипту на странице, поэтому XSS позволяет украсть токен. Кука с HttpOnly скрыта от JavaScript, но тогда нужна защита от CSRF, например SameSite и токены.

Почему нельзя просто зашифровать пароли?

Шифрование обратимо: тот, кто получит ключ, расшифрует все пароли сразу. Хеш-функция для паролей необратима, и серверу достаточно сравнить результат при входе.

Что отвечать, если я не работал с безопасностью?

Скажите об этом прямо, но покажите понимание принципов и опишите, какие меры вы применяли по умолчанию: параметризованные запросы, проверку прав, хранение секретов вне кода. Честный ответ с рассуждением оценивается выше, чем выученное определение.