Хабрахабр

Шпаргалки по безопасности: 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 в своем приложении вы используете какой-либо фреймворк, то стоит изучить его, а не слепо использовать, как это часто делают. Прочтите внимательно документацию, особенно ту часть, которая касается безопасности. Не оставляйте его работать на настройках по умолчанию! У каждого фреймворка есть свои нюансы, особенно когда это касается безопасности, так что знать их очень важно.

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

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

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

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

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