сеньорчикОткрыть в Telegram
← вся теориятеория к собесу · FastAPI, Django и API

Веб-безопасность API

Веб-безопасность: типовые дыры бэкенда

Безопасность - раздел, где заученные названия не спасают: собес проверяет, понимаешь ли ты МЕХАНИЗМ каждой дыры и её лечение. Инъекции, XSS, CSRF, хранение паролей, секреты - джентльменский набор, незнание которого на бэкенде это красный флаг.

Типовые формулировки: «как защититься от SQL-инъекции?», «CORS это защита?», «как хранить пароли».

Инъекции и XSS: отделить код от данных

SQL-инъекция рождается из склейки пользовательского ввода в текст запроса - ввод становится частью SQL-кода. Лечит параметризованный запрос или ORM: значения передаются ОТДЕЛЬНО от кода SQL, драйвер их не интерпретирует как команды. Конкатенация ввода в запрос - прямой путь к дыре.

XSS (cross-site scripting) - из непроэкранированного вывода: чужой скрипт попадает на страницу и исполняется в браузере жертвы. Лечит экранирование вывода плюс CSP (Content-Security-Policy), ограничивающий, откуда грузятся скрипты. Общий принцип обеих дыр один: отделяй код от данных.

// Mass assignment сюда же по духу: биндить надо белый список полей, а не сущность целиком, иначе клиент проставит is_admin.

# дыра:
db.execute(f"SELECT * FROM u WHERE name='{name}'")
# безопасно — значение отдельно от SQL:
db.execute("SELECT * FROM u WHERE name=:n", {'n': name})
SQL-инъекция
подстановка ввода в SQL; лечится параметризацией
XSS
внедрение скрипта через непроэкранированный вывод

CSRF, CORS и хранение секретов

CSRF (cross-site request forgery) - чужой сайт шлёт запрос под сессией жертвы (браузер сам приложит куки). Лечат CSRF-токеном и SameSite-cookie; API на bearer-токене менее уязвим, так как токен не отправляется автоматически. А вот CORS (cross-origin resource sharing) это НЕ серверная защита: это механизм браузера, он лишь ослабляет same-origin для разрешённых origin. curl его игнорирует - считать CORS защитой опасное заблуждение.

Пароли хранят необратимым медленным соль-хешем - bcrypt или argon2, не открыто и не быстрым MD5 (быстрый хеш перебирается на GPU). Секреты держат в env или секрет-менеджере, не в git и не в образе; токены и пароли гоняют только по https.

// Ещё гигиена: не логировать секреты и ПДн (персональные данные), не отдавать стектрейс наружу, патчить уязвимые зависимости (CVE - common vulnerabilities and exposures), валидировать URL против SSRF (server-side request forgery).

CSRF
запрос с чужого сайта под сессией жертвы
CORS
браузерное ослабление same-origin для разрешённых origin

Как отвечать: «CORS защищает мой API?»

Нет, это частое заблуждение. CORS - механизм самого браузера: он решает, можно ли фронту с одного origin читать ответ API с другого, то есть контролируемо ослабляет same-origin-политику. Но это ограничение исполняется на стороне браузера, поэтому любой клиент, которому браузер не указ - curl, Postman, серверный скрипт - просто игнорирует CORS и дёргает мой API напрямую. Реальная защита это аутентификация, авторизация, параметризованные запросы и валидация входа на сервере. CORS я настраиваю ради легитимного фронта, а не как барьер от злоумышленника.

Развеяно ядро заблуждения (CORS исполняет браузер, curl игнорирует), объяснено назначение CORS и названа настоящая защита - точное понимание модели угроз.

На чём валят

  • Строить SQL конкатенацией ввода вместо параметризованного запроса - прямая инъекция.
  • Считать CORS серверной защитой: он исполняется браузером, curl его игнорирует.
  • Хранить пароли открыто или быстрым хешем (MD5); класть секреты в git или образ.
  • Отдавать стектрейс и детали ошибки наружу - подсказка атакующему про стек и структуру.

Проверьте себя

Пять вопросов из банка по этой подтеме. Всего их 12, остальные разбираются в тренажёре.

  1. #web_security1 / 5
    Откуда берётся SQL-инъекция и что её надёжно закрывает?
    A)Из отсутствия шифрования соединения; закрывается переводом базы данных на TLS
    B)Из медленных запросов к базе; закрывается добавлением подходящих индексов на таблицы
    C)Из склейки SQL со строкой ввода; лечит параметризованный запрос
    D)Из слабых паролей к базе; закрывается их регулярной принудительной сменой
    показать ответ и разбор
    +C)Из склейки SQL со строкой ввода; лечит параметризованный запрос

    // разбор: SQL-инъекция возникает, когда пользовательский ввод склеивают в текст запроса: злоумышленник дописывает своё условие (' OR 1=1--). Надёжное лечение — параметризованные запросы (плейсхолдеры), где драйвер передаёт значения отдельно от кода SQL, или ORM, делающий это за вас. Экранирование вручную ненадёжно. Никогда не строить SQL конкатенацией ввода.

  2. #web_security2 / 5
    Пользовательский текст выводится на страницу как есть, и в нём есть <script>. Что за уязвимость и лечение?
    A)CSRF: лечится добавлением скрытого токена в каждую форму на сайте приложения
    B)SQL-инъекция: лечится параметризацией всех запросов к базе данных приложения
    C)Утечка памяти: лечится ограничением длины пользовательского ввода на сервере
    D)XSS: лечится экранированием вывода, а не доверием к вводу
    показать ответ и разбор
    +D)XSS: лечится экранированием вывода, а не доверием к вводу

    // разбор: XSS (cross-site scripting): непроэкранированный пользовательский ввод, попав в HTML, исполняется как скрипт в браузере жертвы (кража cookie/токенов, действия от имени пользователя). Лечение — экранирование/кодирование при ВЫВОДЕ по контексту (HTML, атрибут, JS), а также CSP. Современные шаблонизаторы экранируют по умолчанию; опасно ручное вставление сырого HTML.

  3. #web_security3 / 5
    Что такое CSRF и чем его типично закрывают?
    A)Внедрение скрипта в страницу жертвы; закрывается экранированием пользовательского вывода
    B)Подбор пароля перебором; закрывается ограничением числа попыток входа в систему
    C)Чужой сайт шлёт запрос от имени залогиненного юзера; лечит CSRF-токен или SameSite-cookie
    D)Перехват трафика в открытой сети; закрывается обязательным переводом сайта на HTTPS
    показать ответ и разбор
    +C)Чужой сайт шлёт запрос от имени залогиненного юзера; лечит CSRF-токен или SameSite-cookie

    // разбор: CSRF (cross-site request forgery): вредоносная страница заставляет браузер жертвы отправить запрос на ваш сайт, где та залогинена — cookie прикрепится автоматически, и действие выполнится от её имени. Защита: CSRF-токен, который знает только ваша страница, и cookie с атрибутом SameSite, не отправляемая при межсайтовых запросах. Токен-в-заголовке API (не cookie) к CSRF менее уязвим.

  4. #web_security4 / 5
    Что на самом деле делает CORS?
    A)Ограничивает частоту запросов с одного домена для защиты от перегрузки
    B)Разрешает браузеру межсайтовые запросы к API с указанных origin
    C)Шифрует межсайтовые запросы, чтобы данные не перехватили при передаче по сети
    D)Защищает сервер от несанкционированных запросов, блокируя их ещё до обработки
    показать ответ и разбор
    +B)Разрешает браузеру межсайтовые запросы к API с указанных origin

    // разбор: Браузер по умолчанию запрещает JS читать ответы кросс-доменных запросов (same-origin policy). CORS — способ серверу ОСЛАБИТЬ это: заголовками Access-Control-Allow-Origin он говорит браузеру, каким origin можно. Важно: CORS — механизм БРАУЗЕРА, не серверная защита. Запрос из curl/бэкенда CORS не остановит — авторизацию по-прежнему проверяет сервер.

  5. #web_security5 / 5
    Как правильно хранить пароли пользователей в базе?
    A)Хешем медленной соль-функции (bcrypt/argon2), а не в открытом виде
    B)В открытом виде, но в отдельной таблице с ограниченным доступом для админов
    C)В зашифрованном виде симметричным ключом, чтобы при необходимости расшифровать обратно
    D)Хешем быстрой функции вроде MD5 или SHA-1, этого для паролей вполне достаточно
    показать ответ и разбор
    +A)Хешем медленной соль-функции (bcrypt/argon2), а не в открытом виде

    // разбор: Пароли хранят как необратимый хеш специальной МЕДЛЕННОЙ функции с солью: bcrypt, scrypt, argon2. Медленность и соль делают массовый перебор и радужные таблицы невыгодными. Обратимое шифрование плохо (утечка ключа = утечка всех паролей), быстрые MD5/SHA — тем более. При входе сравнивают хеши, оригинал не восстанавливают.

дальше

Теорию прочитали. Навык ставится повторением

В Сеньорчике эта подтема идёт в ежедневных сессиях: движок возвращает её, пока ответы не станут уверенными, и ведёт прогресс отдельно по каждой подтеме. Теория внутри тоже бесплатна, лимит только на количество вопросов в день.