Хабрахабр

Шпаргалки по безопасности: REST

Для вызова функций на сервере используются обычные HTTP-запросы с задаваемыми параметрами (для структуризации параметров обычно используют JSON или XML), при этом, строгого стандарта для REST-архитектуры не существует, что добавляет ей гибкости (и, конечно, немного хаоса).
REST позволяет гибко подойти к вопросу безопасности, или, чем грешат многие, не подойти к вопросу совсем. REST — чрезвычайно популярная архитектура веб-приложений. Основываясь на OWASP, мы подготовили список советов, которые помогут вам улучшить безопасность вашего REST-приложения.

В качестве отправной точки в тех редких случаях, когда это тут нужно, мы используем python и Django.

Правило 0

HTTPS

Просто настройте. Пожалуйста. Защита передаваемых данных еще никому не вредила. Даже если вы думаете, что защищать в данный момент нечего, это не всегда будет так и вам все равно придется настраивать HTTPS. Так что настройте его лучше сразу, и всем будет хорошо.

Правило 1

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

Казалось бы, очевидный совет, которым, однако, многие предпочитают пренебрегать. На приложении всегда должна быть аутентификация, даже если вы сейчас думаете, что будете им пользоваться только внутри компании и нет разницы, кто из сотрудников это делает. А если дополнить еще и журналами, то расследование инцидентов и анализ активности станет несоизмеримо проще.

Не используйте токены со значением , для контроля за целостностью, токены всегда должны содержать подпись или MAC! В качестве токенов доступа в данный момент считается хорошим тоном использовать JWT (JSON web tokens). Подпись к тому же подтверждает не только целостность сообщения, но и личность отправителя. Подпись предпочтительнее в силу того, что ключи генерации и верификации у MAC совпадают (или могут быть легко вычислены друг из друга), то есть если сервер в состоянии проверить значение MAC, то он может и генерировать его значения.

Правило 2

Запретите те HTTP методы, которыми вы не пользуетесь

Сконфигурируйте на сервере белый список тех методов, с которыми вы работаете (GET, POST, PUT и т. д.) и отклоняйте все, что под этот список не подпадает. Вряд ли на продакшене вашему серверу нужно обрабатывать запросы типа TRACE (данный метод является составляющей XST-атаки (Cross-Site Tracing), которая состоит из XSS-атаки и метода TRACE или TRACK. Это атака позволяет, например, украсть куки пользователя, даже если они помечены как HttpOnly). Чем меньше информации о вашей инфраструктуре доступно снаружи — тем лучше.

Правило 3

Разграничьте доступ

Всем ли вашим пользователям нужны все методы, например, DELETE? Если вы не хотите, чтобы какие-то пользователи имели возможность проводить определенные операции — настройте разграничение доступа в вашем приложении. Например, обычному пользователю доступен только метод GET на часть функций, менеджеру — GET и POST и т. д. Для этого стоит задать роли в БД, которые можно будет выдавать пользователям для удобства управления доступом.

В итоге у каждой функции будет блок проверки приблизительно такого типа:

if request.POST and user.is_manager: do_stuff()

Правило 4

Задумайтесь об ограничении количества запросов

Если вы думаете, что ваши пользователи не должны отправлять вам сто тысяч запросов в секунду, то следует это число ограничить. Используйте API-ключи или любой другой удобный для вас механизм с целью отслеживания и ограничения количества запросов, которые будут обрабатываться в определенный период времени от одного пользователя. Для Django данную функциональность, например, предоставляет django-ratelimit, где в качестве идентификатора для ограничения можно задать различные параметры, не обязательно API-ключи, а, можно IP-адрес.

Правило 5

Обязательно производите валидацию/санитизацию входных данных

никогда не доверяйте передаваемым входным параметрам, всегда проводите валидацию/санитизацию;

  • если это возможно (и там, где это возможно), поставьте ограничение на длину/тип/формат входных данных и самого запроса. Отклоняйте все запросы/передаваемые данные, превышающие заданную вами длину или не совпадающие с типом/форматом;
  • при обработке строк всегда экранируйте все спецсимволы;
  • если вы используете фреймворк, то большинство из них содержат собственные встроенные инструменты валидации и санитизации (навскидку из популярных — Django (python) и Yii2 (php)), так что важно изучить их возможности и, если какой-то необходимый вам аспект не покрыт — найти библиотеку, которая закрывает это, либо написать таковой функционал самостоятельно;
  • ведите учет ошибок валидации, если запросы каких-то пользователей постоянно проваливают валидацию — задумайтесь над автоматической блокировкой подобных пользователей;
  • убедитесь, что ваш парсер входных параметров (или его текущая версия) не подвержен каким-либо атакам сам по себе.

Правило 6

Не отдавайте больше информации, чем необходимо

Если какой-то запрос вызвал ошибку в приложении, или оно просто по какой-то причине в данный момент недоступно — не сообщайте в ответе подробности, возвращайте максимально абстрактное сообщение об ошибке. Некоторые сервера по умолчанию возвращают stacktrace после ошибки, так что убедитесь, что вы перенастроили данную логику.

Правило 7

Всегда ведите журналы

Пусть каждое событие (аутентификация, ошибка, запрос и т.д.) заносится в логи максимально подробно. Разнесите их логически для более удобного поиска по ним в случае необходимости. На всякий случай перед записью в журналы проводите санитизацию записываемых данных.

Правило 8

Правильно указывайте Content-Type — это важно!

Чтобы браузер (или клиент) корректно считывал предоставляемые данные, важно, чтобы был верно указан Content-Type, соответствующий предоставляемым данным. В случае с браузерами стоит также выставить заголовок X-Content-Type-Options: nosniff, дабы предотвратить попытки браузера обнаружить другие Content-Type помимо того, который был послан в действительности (мера противодействия XSS-атакам).

Правило 9

Проводите валидацию Content-Type

  1. Стоит настроить отклонение запросов, если их Content-Type отличается от их содержимого. Это позволит снизить риск неверной обработки данных, которая может привести инъекции или исполнения кода у сервера/клиента.
  2. Также стоит отклонять запросы, Content-Type которых вы не поддерживаете, или у которых данный заголовок вообще отсутствует. Избегайте также прямых ответов о том, какой Content-Type функция принимает/выдает, если это не является необходимым (это поможет избежать XXE-атак).
  3. В REST сервисах является обычным делом поддерживать несколько типов ответов(например json и xml) и клиент указывает предпочтительный тип ответа в заголовке Accept при запросе. Избегайте копирования содержимого заголовка Accept в Content-Type ответа в качестве механизма выставления данного заголвка. Отклоняйте также запросы, у которых заголовок Accept прямо не содержит хотя бы один из поддерживаемых типов.

Правило 10

Не забывайте про настройку Cross-Origin Resource Sharing (CORS)

CORS — это стандарт, описывающий работу с кросс-доменными запросами. Если ваше приложение не поддерживает CORS, отключите работу с этим типом заголовков. Если же его использование у вас необходимо, политика доступа должна быть максимально конкретной и строгой.

Правило 11

Не раскрывайте параметры в URL

Все чувствительные данные (пароли, ключи, токены и логины желательно тоже) должны находится внутри тела запроса или в заголовках, но ни в коем случае не появляться в URL. Если вам необходимо передать чувствительные данные через метод GET, то поместите их в заголовок.

Нельзя:
example.com/controller/123/action?apiKey=a53f435643de32

Можно:
example.com/controller/123/action

Заголовки:
Host: example.com
User-Agent: Mozilla …
X-APIkey: a53f435643de32

Правило 12

Задумайтесь над защитой от CSRF атак

Подробнее про все виды защиты вы можете прочитать здесь, а так самым популярным способ снижения риска проведения атак данного типа считается использование CSRF-токенов.

Правило 13

Изучите свой фреймворк

Если для реализации REST в своем приложении вы используете какой-либо фреймворк, то стоит изучить его, а не слепо использовать, как это часто делают. Прочтите внимательно документацию, особенно ту часть, которая касается безопасности. Не оставляйте его работать на настройках по умолчанию! У каждого фреймворка есть свои нюансы, особенно когда это касается безопасности, так что знать их очень важно.

Теги
Показать больше

Похожие статьи

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть