GraphQL - Безопасность - Защита вложенных данных - PullRequest
0 голосов
/ 27 сентября 2018

Давайте предположим, что мое приложение для электронной коммерции.Есть Users, Orders и Products.

. Вам необходимо пройти аутентификацию (с токеном JWT), чтобы иметь доступ к вашим user данным и вашим orders.Эта проверка выполняется в резольверах.

Однако Products являются общедоступными.Вы можете видеть продукты без входа в систему.

Конечно, User имеет Orders, а Order имеет Products

Что делать, если кто-то из внешнего интерфейса делаетэтот запрос:

query IAmEvil {
  products {
    orders {
      users {
         id
         name
         email
       }
    }
  }
}

Этот парень, не прошедший проверку подлинности, будет иметь доступ к users данным.Как я могу предотвратить это?

Нужно ли добавлять правила во все мои средства распознавания для всех вложенных запросов?

Связанная документация:

https://www.apollographql.com/docs/guides/security.html https://www.howtographql.com/advanced/4-security/ https://blog.apollographql.com/securing-your-graphql-api-from-malicious-queries-16130a324a6b https://www.prisma.io/forum/t/graphql-security-protect-nested-data/4519

Ответы [ 2 ]

0 голосов
/ 27 сентября 2018

Одним из, пожалуй, более элегантным решением является использование Row Level Security (RLS) для контроля того, к каким данным у каждого конкретного пользователя есть доступ.Хотя такой подход добавляет некоторую сложность, он особенно привлекателен, если к вашему API обращаются пользователи с разными ролями, которые имеют разные уровни доступа.Именно так postgraphile обрабатывает аутентификацию.

Вы также можете потенциально использовать директивы схемы, чтобы сохранить СУХОЕ состояние и применить некоторую общую логику доступа к набору отдельных полей.Документы Аполлона на самом деле имеют пример того, как именно это .

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

Важно отметить, что подобные проблемы также в первую очередь возвращаются к хорошему дизайну схемы.Например, только то, что отношения существуют, не означает, что они должны (или должны быть) выставлены клиенту.Заказ может включать один или несколько продуктов, и если клиенту необходимо отобразить историю заказов, имеет смысл выставить поля products для типа Order.С другой стороны, должен ли клиент на самом деле знать все заказы для данного Продукта?

Аналогично, если у нас есть поле users в Order, вне какого-либо пользовательского контекста, например,поле, естественно, будет отражать только пользователей (скорее всего, только одного пользователя), связанных с заказом.Возвращать всех пользователей как поля в одном заказе не имеет смысла.Из-за нисходящей природы GraphQL поле обычно ограничивается только контекстом его родителя.В результате можно беспокоиться только о пользовательском контексте на корневом уровне.

Другой, произвольный пример:

query MyOrders {
  orders { # check context for user and limit results to just the logged in user
    user { # user will be based on parent (the order), no need to check context
      orders { # orders will be based on parent (the user), no need to check context  
      }
    }
  }
}

При проектировании звуковой схемы преобразователи для других типов'поля не обязательно должны выполнять какую-либо дополнительную проверку контекста.

0 голосов
/ 27 сентября 2018

Короткий ответ - да, но не на каждом уровне для вложения.

При любом запросе у вас есть пользователь (или его отсутствие) и путь к графику.Это то же самое для запросов типа restful, где вы должны авторизовать запрос.Сложнее, хотя б / с разрешители могут быть добавлены куда угодно.

Вероятно, лучший разговор о том, как Facebook обрабатывает это здесь - https://blog.apollographql.com/graphql-at-facebook-by-dan-schafer-38d65ef075af

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

...