> Куда помещать пароль в HTTP запросе, чтобы он был зашифрован и не был виден сниферу (iOS, Swift)

Уровень: middle · Роль: mobile · Категория: Технические вопросы

Компании: Avito

Стек: iOS, Swift

> Пример ответа

Короткий ответ

Пароль нельзя передавать в query-параметрах или заголовках - они попадают в логи и историю браузера. Безопасный способ: отправлять пароль в теле POST-запроса, но только по HTTPS (TLS). Шифрование на транспортном уровне защищает тело запроса от снифера. Дополнительно можно шифровать пароль на клиенте, но это не заменяет HTTPS, а лишь добавляет защиту на случай компрометации сервера.

Подробное объяснение

Снифер перехватывает трафик на сетевом уровне. Если используется HTTP без TLS, всё тело запроса, включая пароль, видно в открытом виде. HTTPS (TLS) шифрует весь поток: и заголовки, и тело. Поэтому ключевой момент - не "куда положить пароль", а "убедиться, что соединение защищено TLS".

Пароль в query-строке (https://api.com/login?password=123) - плохая практика даже с HTTPS: URL попадает в логи сервера, прокси, историю браузера, рефереры. Заголовки (Authorization: Basic ...) тоже логируются чаще, чем тело запроса.

Оптимально: POST + JSON в теле, например {"password": "..."}. Тело запроса не логируется по умолчанию, а при HTTPS оно зашифровано. Дополнительно можно использовать Authorization с токеном после логина, но для передачи самого пароля - только тело.

На практике

В iOS (Swift) это означает:

  • Использовать URLSession с https:// - TLS включён автоматически.
  • Не добавлять исключения для http:// в Info.plist (NSAppTransportSecurity).
  • Отправлять пароль в теле запроса как JSON.
  • Не кэшировать запросы с паролем (URLRequest.CachePolicy).
  • Для чувствительных данных можно добавить клиентское шифрование (например, RSA), но это не защищает от MITM, если нет TLS.

Пример кода

SWIFT
var request = URLRequest(url: URL(string: "https://api.example.com/login")!)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.cachePolicy = .reloadIgnoringLocalCacheData
let body: [String: Any] = ["username": "user@example.com", "password": "secret"]
request.httpBody = try? JSONSerialization.data(withJSONObject: body)
let task = URLSession.shared.dataTask(with: request) { data, response, error in
// обработка ответа
}
task.resume()

Как отвечать на собеседовании

Начни с главного: "Пароль должен передаваться в теле POST-запроса по HTTPS". Затем объясни, почему не в URL и не в заголовках. Упомяни, что TLS - это единственный реальный уровень защиты от снифера, а клиентское шифрование - дополнительная мера, но не замена. Если спросят про логи - скажи, что тело запроса реже логируется, чем URL. Для middle-уровня этого достаточно.

Что проверяет интервьюер

  • Понимание разницы между HTTP и HTTPS, роли TLS.
  • Знание, что query-параметры и заголовки логируются.
  • Умение обосновать выбор места для пароля.
  • Понимание ограничений клиентского шифрования (MITM, компрометация сервера).
  • Базовые знания URLSession и ATS в iOS.

Типичные ошибки

  • Предложение шифровать пароль на клиенте как основную защиту - это не спасает от снифера, если нет TLS.
  • Использование GET с паролем в query - грубая ошибка.
  • Упоминание Authorization: Basic как безопасного способа - заголовок логируется.
  • Игнорирование ATS и разрешение http:// в iOS - это снимает защиту.
  • Утверждение, что "пароль в теле запроса виден сниферу" - неверно при HTTPS.

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью