60 votes

Comment empêchez-vous les attaques imbriquées sur le serveur GraphQL / Apollo?

Comment empêcher une attaque imbriquée contre un serveur Apollo avec une requête telle que:

 {
  authors {
    firstName
    posts {
      title
      author {
        firstName
        posts{
          title
          author {
            firstName
            posts {
              title
              [n author]
                [n post]
            }
          }
        }
      }
    }
  }
}
 

En d'autres termes, comment pouvez-vous limiter le nombre de récurrences soumises dans une requête? Cela pourrait être une vulnérabilité potentielle du serveur.

60voto

stubailo Points 4611

Au moment de l'écriture, il n'y a pas une fonctionnalité intégrée dans GraphQL-JS ou d'Apollon Serveur pour répondre à cette préoccupation, mais c'est quelque chose qui devrait certainement avoir une solution simple comme GraphQL devient de plus en plus populaire. Ce problème peut être résolu avec plusieurs approches à plusieurs niveaux de la pile, et doivent également toujours être combiné avec limitation du débit, de sorte que les gens ne peuvent pas envoyer trop de requêtes à votre serveur (ce qui est un problème potentiel avec le RESTE aussi).

Je vais juste la liste de tous les différentes méthodes que je pense, et je vais essayer de garder cette réponse jusqu'à ce jour que ces solutions sont mises en œuvre dans différents GraphQL serveurs. Certains d'entre eux sont assez simples, et certains sont plus complexes.

  1. Requête de validation: Dans tous les GraphQL serveur, la première étape de l'exécution d'une requête de validation - c'est là que le serveur tente de déterminer s'il y a des erreurs graves dans la requête, de sorte que nous pouvons éviter l'utilisation réelle des ressources de serveur si on peut trouver qu'il existe une erreur de syntaxe ou argument non valide à l'avant. GraphQL-JS est livré avec une sélection de règles par défaut qui suivent un format assez similaire à ESLint. Tout comme il y a une règle pour détecter infini de cycles dans les fragments, on pourrait écrire une règle de validation pour détecter les requêtes avec trop de nidification et de les rejeter à l'étape de validation.
  2. Délai d'expiration de requête: S'il n'est pas possible de détecter qu'une requête est trop gourmandes en ressources de manière statique (et peut-être même peu profonde, les requêtes peuvent être très cher!), ensuite, il suffit d'ajouter un délai pour l'exécution de la requête. Cela a quelques avantages: (1) c'est une limite qui n'est pas trop dur à comprendre, et (2) cela aidera également à des situations où l'un des backends prend trop long à répondre. Dans de nombreux cas, un utilisateur de votre application préférez un champ manquant plus d'attendre 10 secondes pour obtenir une réponse.
  3. Requête de la liste blanche: C'est probablement le plus impliqués, méthode, mais vous pouvez compiler une liste de requêtes à l'avance, et de vérifier toutes les requêtes entrantes en fonction de ces critères. Si vos demandes sont totalement statique (vous n'avez pas à faire toute la dynamique de génération de requête sur le client avec quelque chose comme Relais) c'est le plus fiable. Vous pouvez utiliser un outil automatisé pour tirer des chaînes de requête de vos applications lorsqu'ils sont déployés, ainsi que dans le développement vous écrire ce que les requêtes que vous voulez, mais dans la production que vous souhaitez laisser passer. Un autre avantage de cette approche est que vous pouvez ignorer la requête de validation entièrement, puisque vous savez que toutes les requêtes possibles sont valables déjà. Pour plus d'avantages de la statique et de requêtes de la liste blanche, lisez ce post: https://dev-blog.apollodata.com/5-benefits-of-static-graphql-queries-b7fa90b0b69a
  4. Requête coût limiter: (Ajouté dans un edit) Semblables à des délais d'attente de requête, vous pouvez attribuer un coût à différentes activités au cours de l'exécution de la requête, par exemple une requête de base de données, et de limiter le coût total que le client est capable d'utiliser dans la requête. Cela peut être combinée avec la limitation du maximum de parallélisme d'une seule requête, de sorte que vous pouvez empêcher le client d'envoyer quelque chose qui initie des milliers de demandes parallèles à votre backend.

(1) et (2) en particulier sont probablement quelque chose que chaque GraphQL serveur, par défaut, d'autant plus que beaucoup de nouveaux développeurs peuvent ne pas être conscient de ces préoccupations. (3) ne fonctionne que pour certains types d'applications, mais ce pourrait être un bon choix lorsqu'il y a très strictes de performances ou d'exigences en matière de sécurité.

15voto

Andy Carlson Points 1233

Pour compléter le point (4) dans stubailo réponse, voici quelques Node.js implémentations qui imposent des coûts et de la profondeur des limites sur l'arrivée de GraphQL documents.

Ce sont des règles personnalisées en complément de la phase de validation.

3voto

Tamlyn Points 2728

Une variation sur requête d'une liste blanche est une requête de signature.

Pendant le processus de génération, chaque requête est de signer cryptographiquement à l'aide d'un secret, qui est partagée avec le serveur, mais pas livré avec le client. Ensuite, lors de l'exécution, le serveur peut valider qu'une requête est authentique.

L'avantage par rapport à une liste blanche, c'est que l'écriture de requêtes dans le client ne nécessite pas de modifications sur le serveur. Ceci est particulièrement utile si plusieurs clients d'accéder au même serveur (web, desktop et mobile apps).

2voto

Schrax Points 11

Pour limiter le coût des requêtes, vous pouvez utiliser une analyse graphql-cost

Il s'agit d'une règle de validation qui analyse la requête avant de l'exécuter. Dans votre serveur GraphQL, il vous suffit d’affecter une configuration de coût à chaque champ de votre mappe de types de schéma de votre choix.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X