Соль

Зачем солить

Некоторые облачные сервисы хотят двустороннего общения для нотификаций: рассказать вашему backend о завершении долгой операции, показать случившиеся ошибки, предупредить о низком балансе платных услуг — вся вот эта история. И если для общения с сервисами мы привыкли использовать HTTP-запросы, то в обратную сторону есть много вариантов: от проверок статуса раз в десять минут и до постоянного WebSocket или HTTP/2 подключения с нотификациями в реальном времени. Самый простой способ это HTTP callbacks. Вы задаете в админке URL своего бэкенда, а облачный сервис в случае интересных событий делает HTTP-запрос к этому URL с дополнительный информацией в теле запроса. Обратная сторона простоты это безопасность. Как убедиться, что запрос сделал именно облачный сервис, а не злобный хакер Вася? Несколько способов под катом.

Передача и проверка токена

Самый простой способ внутри самого простого способа: в админке вы задаете или генерируете токен (например, GUID), который облачный сервис передает в каждом запросе. А на стороне своего бэкенда просто проверяете этот токен.

Очевидный минус: если злоумышленник подслушает трафик между вашими сервисами, то он узнает токен и сможет делать запросы от имени сервиса. От этого хорошо защищает HTTPS, но есть нюансы. Например, трафик между серверами может не шифроваться для ускорения работы. Или вы можете отлаживать ваш бэкенд на локальной машине, сидя в Старбакс без VPN. Звучит дико, но в жизни всякое бывает.

HTTP-авторизация на стороне вашего бэкенда

От токена отличается только тем, что проверка переносится из вашего кода на уровень веб-сервера, который вы используете для обработки запросов. Задаете логин плюс пароль в nginx/expressjs/Django/Rails/whatever, их же в админке облачного сервиса, после чего все проверки делаются автоматически. Но подслушать логин с паролем можно точно так же, а HTTPS имеет неприятную особенность отключаться «на минутку мне только локально отладить».

Фильтрация по IP

Если запросы по URL для http callback разрешить только с определенного IP-адреса, то у хакера будут большие проблемы такой запрос организовать. Не то чтобы это было невозможно (если ответ не требуется, то нужную последовательность TCP-пакетов можно и организовать), но технически трудно. Засада тут в другом — у облачного сервиса может быть много IP-адресов, с которых он отправляет запросы, что делает такую защиту слишком ненадежной в простой реализации и слишком сложной, если нужна надежность.

MD5-подпись с солью

Хороший сбалансированный способ с общим секретом, который мы используем в Voximplant. В админке задается произвольная текстовая строка («криптографическая соль», в роли которой хорошо подходит GUID), после чего для каждого запроса облако Voximplant считает MD5-хэш от данных аккаунта, запроса и соли. На стороне бэкенда, зная соль, можно также посчитать хэш и сравнить с указанным в запросе. Если совпало — значит все хорошо. А если нет, то можно принимать поздравления в создании действительно популярного сервиса, на который даже хакеры заходят.

Это только несколько простых способов защиты, используемых на практике в HTTP API крупных проектов. Знаете что-то еще интересное? Делитесь в комментариях!