Наличие стороннего проекта - это здорово, если это безопасно для пользователей.
Предупреждение
Эта статья содержит важные советы для новичков, создающих свое первое веб-приложение, а также любительские приемы взлома, которые могут значительно повлиять на работу веб-приложения. Используйте их с осторожностью, немного поиграйте с ними в других веб-приложениях, но, золотое правило 0: «Не делайте другим того, чего вы не хотите делать с вами».
Студенты-информатики часто хотят кодировать следующий Airbnb, следующий Facebook. Как только они узнают, как работает Интернет, они начинают следовать руководствам и создают свое первое веб-приложение, стремясь к звездам, думая о своем офисе в Кремниевой долине.
Будучи студентом, я был одним из них. Через несколько дней я закодировал следующие TripAdvisor + Airbnb + Maps + Rome2Rio. И я допустил ошибку в коде и безопасности.
Когда я слышу о веб-приложении стороннего проекта или даже о стартовом выпуске, я не могу удержаться от проверки исходного кода и сети (Cmd + Opt + J). Мой предыдущий технический директор всегда говорил: «Истина находится на вкладке« Сеть »».
Из всех недавно появившихся проектов, которые я видел, вот подборка распространенных ошибок и способов создания более безопасного приложения:
Золотое правило 1: нет ключа API во внешнем интерфейсе
Неа. Никогда. Ниет. Нада.
«Ключи API в интерфейсе» должны вызывать у вас тревогу.
Я пойду еще дальше: в коде нет ключа API! Фронтенд И бэкэнд.
Имейте в виду, что все, что вы пишете в коде внешнего интерфейса, может прочитать любой (сам React говорит об этом). Фронтенд находится в руках пользователя, он может менять дизайн, менять контент, читать код, читать комментарии, читать логи.
При развертывании внешнего интерфейса вы должны быть уверены, что все, что вы написали (и скопировало!), Может быть прочитано Кевином Митником и не представляет угрозы для ваших пользователей.
В последнем веб-приложении, которое я изучал, интерфейс напрямую запрашивал Google Identity API, включая API-ключ в запросе. Для нас детская игра - создать 1 000 000 фальшивых пользователей со всеми ограничениями по скорости и финансовыми последствиями, которые это может иметь для владельца ключа API. Не доверяешь мне? Посмотрите эти истории о людях, которые таким образом проиграли $ 50 000.
Я просто сказал: «В коде нет ключа API!». Ключ API также не должен присутствовать во внутреннем коде. Я предполагаю, что вы используете GitHub или Gitlab, чтобы управлять своим кодом и делиться им. Предоставить им свои учетные данные - большая угроза безопасности. После этого ваш ключ API будет виден всем разработчикам. Даже если вы удалите его, ваш ключ API можно будет найти в истории коммитов.
Что вы должны сделать?
Интерфейс: все запросы к внешним API должны выполняться вашим сервером.
Например, если вам нужно вызвать Google API, сначала вызовите свой сервер, который вызовет удаленный сервер, обработает результат и вернет его во внешний интерфейс. Я подробно описываю этот вариант в Золотом правиле 2.
Бэкэнд: создайте файл .env, который включает все ваши ключи API, секретные хэши ... Добавьте «.env» в файл .gitignore, чтобы ваш файл остался на вашем компьютере.
При развертывании серверной части не забудьте вручную добавить файл .env на сервер (поскольку он не клонирован с помощью Github). Вы можете пойти еще дальше: создать ключ API для целей разработки, доступный всем вашим разработчикам, и ключ API для производства, к которому имеют доступ только несколько участников.
Золотое правило 2: централизовать запросы
Как мы видели в золотом правиле 1, все запросы, связанные с внешними API, должны выполняться вашим сервером.
У этого подхода много преимуществ:
- Защитите свои ключи API: см. Золотое правило 1
- Держите поставщиков данных в секрете: если вы боитесь конкурентов и не хотите, чтобы они знали ваши процессы и поставщиков данных
- Предварительная обработка результата: вы возвращаете только то, что нужно пользователю, и никакой конфиденциальной информации, которая может быть возвращена внешним API.
- Добавьте IP-адрес вашего сервера в белый список для внешнего API. Таким образом, даже если ваш ключ API будет украден, хакер не сможет напрямую вызвать внешний API, выдавая себя за вас (на самом деле он / она может, но это Сильнее)
- Ускорение операций: браузеры пользователей работают медленнее, чем ваш внутренний сервер. Есть исключения, но давайте предположим, что это общая истина: вам не следует выполнять какие-либо вычисления (даже форматирование / объединение…) в браузере вашего посетителя. Им уже сложно загружать изображения, не майните биткойны на компьютере 15-летней давности!
- Монитор. Каждый запрос, проходящий через ваш API, можно отслеживать и отслеживать. Возможно, вы сейчас не знаете, что вы можете сделать с этими данными, но однажды вам может понадобиться проанализировать их, извлечь закономерности, оценить рост… Если все запросы проходят через ваш сервер, вы можете их записать.
Золотое правило 3: никаких личных данных от серверной части
Персональные данные пользователей не должны быть видны никому!
Веб-приложение, отображающее список пользователей, будет идентифицировать их по псевдониму (например, Twitter), имени (например, Airbnb) или полному имени (например, Facebook).
Но вы никогда не увидите общедоступный веб-сайт, на котором отображаются номера телефонов или адреса электронной почты пользователей; это личные данные, которые необходимо надежно хранить.
То же должно быть и с точки зрения серверной части: серверная часть никогда не должна возвращать конфиденциальные данные. Никогда.
Золотое правило 4: никаких личных данных в JSON Web Token (JWT)
Да, чтобы создать JWT, вам нужен пароль, который знаете только вы.
Да, чтобы проверить JWT, вам нужен пароль, который знаете только вы.
НЕТ, чтобы читать JWT, вам нужен только один веб-сайт: jwt.io.
Позвольте мне сказать это еще раз:
Веб-токен JSON можно прочитать (легко)!
JWT используется для безопасной передачи информации между сторонами в виде объекта JSON. Эту информацию можно проверить и доверять, потому что она имеет цифровую подпись. JWT могут быть подписаны с использованием секретного или открытого / закрытого ключа.
При таком определении новички часто думают, что JWT защищен секретным / закрытым ключом. Но это не так!
JWT похож на бумажный документ, закрытый прозрачной крышкой: никто не может его изменить, но убедитесь, что каждый может его прочитать.
Так что даже не думайте о записи конфиденциальных данных, если вы используете JWT в качестве токена аутентификации!
Последнее веб-приложение, которое я проверял, делало это правильно: сохраняло только user_id в JWT для аутентификации.
БУУУУУУУУУУТТТТТТ
Они хранили токен JWT ВНУТРИ базы данных.
Основная причина использования JWT вместо случайного токена заключается в том, что JWT не нужно хранить в базе данных, так как он может быть автоматически подтвержден.
Золотое правило 5. Хешируйте пароли или не спрашивайте пароли
Это золотое правило очевидно, и, как правило, это первое, чему учатся разработчики. Может быть, потому что они сами используют один и тот же пароль для всех сайтов и хотят оценить риск (высокий).
При разработке веб-приложения с использованием аутентификации пользователя пароль необходимо хешировать, как только серверная часть его получит. И только потом, хранится в базе данных.
Я лично использую алгоритм bcrypt для хеширования паролей пользователей.
Безпарольная аутентификация
На самом деле, это не совсем так: раньше я был большим поклонником bcrypt, а теперь предпочитаю аутентификацию без пароля.
При аутентификации без пароля сервер отправляет пользователю код по SMS или ссылку по электронной почте. Затем пользователю нужно только скопировать код или щелкнуть ссылку.
Этот метод лучше для пользователя (меньше пароля), безопаснее (нет проблемы с одинаковым паролем везде) и проще в разработке: нет забытых паролей и возможности смены пароля ...
Скажу вам, пароли мертвы.
Золотое правило 6. Не копируйте слепо
Когда новички хотят создать свой первый API, они часто следуют инструкциям, объясняющим, как создавать, обновлять, перечислять и удалять записи.
Отлично.
Но как только проект веб-приложения запущен, все CRUD-методы не нужны всем ресурсам. Возможно, ресурсу Книги нужен метод GET для вывода списка всех книг библиотеки. Но для ресурса User этот метод не должен быть разрешен!
Когда я проверяю веб-приложение, мне нравится разбираться в структуре базы данных и перечислять то, что не должно указываться, создавать то, что не должно создаваться (с незначительными последствиями для владельца !!).
Приведу пример: несколько недель назад я проверил прототип веб-сайта Shopping 2.0. Они просили код, полученный по электронной почте, для подтверждения учетной записи. После проверки кода был вызван другой маршрут (POST / пользователь) без какой-либо проверки токенов для создания моей учетной записи. Насколько легко было бы создать 1 млрд пользователей с поддельными адресами электронной почты?
Следует помнить следующее правило: Начинайте ни с чего и разрешайте только то, что вы делаете.
Золотое правило 7. Не знаешь, что делаешь? Не изобретайте колесо заново.
Специально для побочного проекта.
Мне нравится кодировать вещи и функции. Например, аутентификация: я предпочитаю управлять своей собственной базой данных, хранить своих пользователей и их пароли, отправлять себе (своему серверу) электронное письмо с подтверждением.
Но я знаю, что делаю, и уже пробовал другие альтернативы (AWS Cognito и Google Identity).
Но если вы не уверены в процессах = ›Выберите широко распространенный инструмент. Позже у вас будет время, чтобы понять и перейти к чему-то, что у вас больше контроля.
Я даю этот совет, потому что веб-приложение, которое я проверял, использовало Google Identity для управления своими пользователями. Это было отличным решением не подвергать опасности пароли пользователей, поскольку владелец казался новичком.
Сторонний проект веб-приложения - это тяжелая работа. От развертывания внешнего интерфейса до аутентификации пользователя (если она есть) есть чему поучиться, и не стыдно делегировать некоторые важные функции экспертам. Так безопаснее и быстрее.
Золотое правило 8. Проверяйте все вводимые данные на стороне сервера.
Одной проверки внешнего интерфейса недостаточно.
Интересно, какая доля веб-приложений проверяет данные только на стороне внешнего интерфейса.
Все возможные регулярные выражения для проверки электронной почты на стороне внешнего интерфейса бесполезны, если они не созданы на стороне внутреннего интерфейса.
Злоумышленнику проще всего отправить POST в API и изменить формат данных.
А если такое случится… Это не так уж и хорошо…
Во-первых, если злоумышленник отправит сообщение с неожиданным форматом данных, сервер выйдет из строя. Потому что он попытается обработать строку, но злоумышленник отправит целое число (или любой другой тип). Злоумышленник может добавить атрибуты или удалить обязательный атрибут в запросе. Возможна некоторая обработка ошибок, но этого недостаточно для защиты сервера.
Во-вторых, если входные данные не проверены, злоумышленник может выполнить SQL-инъекцию. SQL-инъекция - это атака, при которой пользователь может вставлять операторы SQL во входные данные. Этот оператор SQL можно интерпретировать как команду, выполняемую в базе данных. SQL Injection занимает первое место в десятке лучших веб-уязвимостей OWASP.
Знаменитое правило, которое следует запомнить: Никогда не доверяйте своему пользователю
Золотое правило 9: мониторинг, журнал и проверка
Думаю, на многих свежих веб-сайтах не настроены инструменты для мониторинга. Потому что через несколько недель после того, как я обнаружил и изменил определенный веб-сайт, все еще были те же нарушения.
Если бы у них были инструменты для мониторинга и ведения журналов, они бы увидели запросы к бэкэнду напрямую с загадочного IP-адреса 193.XX.XX.XXX.
Мониторинг - это третий глаз приложения. По-разному!
Мониторинг помогает понять, как пользователи взаимодействуют с веб-интерфейсом. Это помогает обнаруживать сбои (если IP-адрес запрашивает одно и то же 15 раз, это не очень хорошо)…
На самом деле, я не буду увеличивать эту статью: - Вы слышали, что данные - это новая нефть, верно? Поймите, почему и создайте данные.
Мониторинг помогает мне спать по ночам. На моих серверах настроен полный мониторинг; если один из них перестанет работать, я буду уведомлен в течение 2 минут. Если нет: новостей нет, хорошие новости.
Помимо полезности мониторинга, возможность видеть, кто использует наше собственное приложение, что они делают и как долго ... продолжать писать код - это супер мотивация!
Золотое правило 10. Реализуйте API-шлюз
Некоторые из предыдущих правил долго внедрять и поддерживать: мониторинг, ведение журнала, ограничение скорости. Внедрение API-шлюза - отличное решение, если вы хотите действовать быстро и безопасно.
Шлюз API - это фасад, который предоставляет интерфейс API. Это похоже на входную дверь приложения, через которую проходят все запросы, сделанные на сервере.
Настройка шлюза API позволяет разработчикам сосредоточить свое внимание на этой части. Разработчики часто совершают ошибку, имея сверхзащищенный интерфейс, но интерфейс не требует особого внимания по сравнению с API Gateway.
Кроме того, API-шлюз устраняет несколько проблем, обсуждаемых в этой статье:
- Конкретное решение о том, какие маршруты открыты для мира (даже после того, как логика CRUD была скопирована со всеми вашими объектами API (Золотое правило 3))
- Предел скорости по умолчанию, который можно легко снизить.
- Ограничение размера полезной нагрузки по умолчанию (в некоторых из них)
- Мониторинг и ведение журнала: API-шлюз похож на плату за проезд, все, что использует ваши маршруты, регистрируется и записывается.
- Другие крутые и простые вещи, которые облегчают жизнь
Золотое правило 11: забудьте о гамаке
Безопасность - это ежедневная работа, в зависимости от размера вашей аудитории вы должны потратить от нескольких часов до нескольких дней, проверяя, что все работает правильно, читая журналы, исследуя, чтобы найти подозрительное поведение.
Идти дальше?
Этот список представляет собой лишь часть лучших практик при разработке веб-приложений. Некоторые перечисленные здесь Золотые правила устраняют некоторые из 10 лучших веб-уязвимостей OWASP, но частично, а не все из них. Эти Золотые правила помогут новичкам создать более безопасное приложение, но работа только начинается здесь! Я хотел бы получить отзывы экспертов, чтобы улучшить эту статью и исправить ее!
Подумайте о сторонних проектах своих друзей: отправьте им эту статью, прежде чем я украду электронные письма их пользователей! 😜
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJtZXNzYWdlIjoiSGV5ISBJZiB5b3Ugd2VudCB0aGF0IGZhciwgSSB0aGluayBJIGRlc2VydmUgc29tZSBjbGFwcyBvbiBNZWRpdW0hIDspIELDqXJhbmdlciJ9.gLlL1qC75B-_l3m8n98Xz9P1qYGvFgoqEvnobjCOYRU