Исследование безопасности tRPC: Охота за уязвимостями в современных API

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

В этой статье я хочу рассказать о своем исследовании, посвященном tRPC. Сначала мы рассмотрим концепции tRPC, а затем перейдем к анализу поверхности атаки приложения tRPC.

tRPC с точки зрения разработчика

tRPC расшифровывается как "TypeScript Remote Procedure Call" и использует возможности TypeScript для обеспечения безопасности типов на границах клиент-сервер. Это означает, что tRPC позволяет разработчикам создавать API, в которых входные и выходные данные автоматически проверяются на соответствие типам, что значительно снижает риск возникновения ошибок во время выполнения из-за несовпадения типов данных или неожиданных структур данных.

Давайте узнаем, как это работает:

Определение API

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

Определение маршрутизаторов

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

В этом примере определены две процедуры: одна для чтения данных, другая - для их изменения. Возможно, что некоторые процедуры могут получать входные данные от клиента.

Интеграция на стороне клиента

tRPC автоматически генерирует клиентскую библиотеку на основе типов вашего API. Эта клиентская библиотека позволяет внешнему приложению вызывать серверные процедуры напрямую, как локальные функции, без необходимости беспокоиться о HTTP-методах, заголовках или путях. Когда вы вызываете серверную процедуру, типы выводятся непосредственно из определений TypeScript сервера. Это означает, что разработчик получает автозаполнение предложений в редакторе и проверку типов во время компиляции, что помогает предотвратить проблемы, связанные с предоставлением неправильного типа или структуры данных в запросах или ответах API. Вот пример:

Клиент вызывает метод 'addUser'; результат этого метода считывается из ответа и отображается в DOM. Ссылка httpBatchLink особенно полезна в сценариях, когда клиенту необходимо отправить несколько запросов на сервер одновременно. В качестве альтернативы httpLink можно использовать для выполнения стандартных отдельных HTTP-запросов от клиента к серверу tRPC.

Обмен данными между клиентом и сервером (транспортный уровень)

tRPC использует транспортные механизмы (обычно HTTP/HTTPS).

До сих пор мы изучали концепции tRPC. Далее мы рассмотрим tRPC с точки зрения исследователя.

tRPC с точки зрения исследователя

Чтобы выявить уязвимости в tRPC, мы должны принять во внимание следующие шаги:

  1. Определение стиля tRPC

  2. Исследование tRPC

  3. Анализ поверхности атаки

Шаг 1: Определение tRPC

Самый важный вопрос, который мы должны решить при тестировании API, это какой стиль используется. Каждый API имеет свой стиль. Поняв стиль, мы сможем легче провести разведку и обнаружить уязвимости. Как мы можем определить, что стиль API цели - tRPC?

Как мы видели в предыдущем разделе, процедуры в tRPC бывают двух видов: Query и Mutation. Метод GET используется для Querie, которые предполагают чтение данных, а метод POST - для Mutation, то есть для изменения данных. У нас есть следующие общие шаблоны:

GET  /ProcedureName
POST /ProcedureName

GET  /getUsers
POST /addUser

Иногда приложение использует httpBatchLink для отправки всех запросов вместе. В этом случае в строку запроса включается параметр 'batch':

GET  /getUsers?batch=1

Формат ошибки

Еще один способ определить tRPC - понаблюдать за тем, какую ошибку возвращает сервер для различных состояний. Если процедура не была определена для конечной точки на стороне сервера, изменение метода HTTP приведет к ошибке со стороны сервера:

Изменение типа параметра

Изменение типов параметров в запросе и выдача ошибки могут помочь нам в определении tRPC:

Формат данных запроса/ответа

Формат данных, который мы можем использовать в tRPC, - это JSON. В примере ниже показана структура данных в двух сценариях: httpLink и httpBatchLink:

Комбинируя вышеописанные техники, мы можем определить tRPC.

Шаг 2: tRPC Recon

Во время разведки API доступ к документации может помочь нам в анализе цели. Наша цель может сделать свой API общедоступным, к которому мы можем получить доступ, используя различные техники. Цель может использовать панель trpc. Этот инструмент предназначен специально для документирования конечных точек tRPC.
Вот простой вариант реализации:

Разработчик может определить промежуточное ПО для панели trpc и указать конечную точку для доступа к панели, как показано в примере ниже:

Если мы отправим запрос на "/panel", то сможем просмотреть список всех процедур и получить полный доступ к документации, что упростит нам процесс поиска уязвимостей. Эта конечная точка может отличаться в разных целях. Лучший способ найти эту конечную точку - использовать фаззинг и методы, описанные ниже:

Google Dorking

site:TARGET.tld intitle:"tRPC.panel()" inurl:/panel
site:TARGET.tld intitle:"tRPC.panel()"

API Fuzzing

id: trpc-panel

info:
  name: Public trpc-panel
  author: LogicalHunter
  severity: info
  tags: exposure,trpc

http:
  - method: GET
    path:
      - "{{BaseURL}}/panel"
      - "{{BaseURL}}/trpc-panel"
      - "{{BaseURL}}/trpc"
      - "{{BaseURL}}/trpc/panel"
      - "{{BaseURL}}/api/panel"
      - "{{BaseURL}}/api/trpc-panel"
      - "{{BaseURL}}/docs"
      - "{{BaseURL}}/doc"
      - "{{BaseURL}}/api/docs"
      - "{{BaseURL}}/api/doc"
      - "{{BaseURL}}/api/trpc/panel"
  
    headers:
      Accept: text/html
    stop-at-first-match: true

    matchers-condition: and
    matchers:
      - type: word
        part: body
        words:
          - "tRPC.panel()"

      - type: status
        status:
          - 200

Сторонние источники

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

https://www.postman.com/explore
https://apis.guru/
https://github.com/public-apis/public-apis
https://rapidapi.com/search/

Анализ атаки

Нам необходимо рассмотреть два общих сценария:

  1. Документация доступна

  2. Документация недоступна

Документация цели доступна

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

POST /AuthProcedure
POST /authUser 

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

Затем мы должны рассмотреть следующий вопрос: Какие уязвимости существуют в различных процедурах? На этом этапе, в зависимости от того, является ли операция Query или Mutation, мы пытаемся определить различные уязвимости. Для Query и Mutation мы должны изучить следующие классы уязвимостей:

Документация по цели недоступна

Во втором сценарии, при отсутствии доступа к документации, нам необходимо составить карту целевого API. Для этой задачи можно использовать такие инструменты, как Logger++. Как правило, мы просматриваем приложение и отфильтровываем протоколируемые запросы tRPC с помощью Logger++. Затем мы можем экспортировать конечные точки и приступить к поиску различных уязвимостей.

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

Fuzz(METHOD) /FUZZ(ProcedureName)

POST /addUsers

Possible Endpoints: 
METHOD /getUsers
METHOD /deleteUsers
METHOD /updateUsers

Более того, для практического опыта я создал уязвимое приложение tRPC, доступ к которому можно получить через мой GitHub.

Надеюсь, вам понравилось читать эту статью.

Источник: https://habr.com/ru/articles/786914/


Интересные статьи

Интересные статьи

Аналитики исследовательского центра A2:Research провели исследование и выяснили, какие системы умного дома устанавливают респонденты, какие гаджеты выбирают и сколько готовы доплатить за покупку ...
На этой неделе мы отправимся в интересный и сложный мир механизм хэширования паролей, и рассмотрим очень простое изменение, которое Вы должны сделать в своих приложениях для повышения безопасности.
В настоящее время в связи с обстановкой в мире во многих отраслях производства наблюдается проблема с поставкой запасных частей для оборудования и не только. В ситуации, когда поставка оригинальных де...
Продолжая разбор ситуации с системами безопасности, который мы начали в прошлый раз с видеонаблюдения (почитать можно в предыдущем посте), я хочу рассказать о вариантах замены для различных устройств,...
Ниже речь пойдет о технологиях работы с голосом в вебе, таких как распознавание и синтез речи. В статье не будет примеров кода или сложного технического описания, моя цель — показать вам ...