Le champ que l'erreur a révélé : les suggestions GraphQL exposent un champ réservé au staff

Sécurité Web & API Niveau 3/4 ~5 min 31 octobre 2026

Le défi

L'API GraphQL de Wrenmoor cache ses champs. Devine un champ : l'erreur propose le vrai nom. Trouve le code d'override de la commande 1042.

Ce que tu vas apprendre

  • Expliquer ce que l'introspection GraphQL expose et pourquoi la désactiver ne suffit pas
  • Utiliser les suggestions de champs de graphql-js pour découvrir les noms de champs qu'un schéma cache
  • Lire les réponses d'erreur d'Apollo Server : code de statut, message et code d'erreur
  • Reconnaître l'absence de contrôle d'autorisation au niveau du champ
  • Masquer les suggestions en production et autoriser les champs sensibles

Compétences testées

Test de sécurité d'APIGraphQLAltération de requêtes

Prérequis

  • À quoi ressemble une requête GraphQL
  • Lire une réponse HTTP en JSON

Comment ça marche

Une API GraphQL sert un seul schéma : tous les types et champs qu'un client peut demander. L'introspection (__schema, __type) permet à n'importe qui de télécharger ce schéma, donc les serveurs de production la désactivent souvent. Apollo Server le fait par défaut quand NODE_ENV=production et répond à une requête d'introspection par GraphQL introspection is not allowed by Apollo Server.

Désactiver l'introspection ne supprime pas le schéma. Chaque requête est toujours validée contre lui, et graphql-js répond à un champ inconnu avec les noms réels les plus proches : Cannot query field "overrideCode" on type "Order". Did you mean "agentOverrideCode"? Une mauvaise supposition à la fois, le schéma caché réapparaît. Clairvoyance automatise cela avec une wordlist, et la Web Security Academy de PortSwigger le couvre dans son sujet GraphQL.

Ici, le nom divulgué est un champ du tableau de bord du support, sur le même type Order que celui utilisé par la boutique. Le resolver vérifie seulement que la commande appartient à l'appelant, pas qui a le droit de lire chaque champ, donc connaître le nom suffit pour le lire. L'OWASP API Security Top 10 appelle cela Broken Object Property Level Authorization (API3:2023).

Erreurs fréquentes

  • S'arrêter à l'erreur d'introspection. Elle cache seulement la liste des champs : la validation des champs continue de parler.
  • Deviner sur le mauvais type. { agentOverrideCode } au niveau racine interroge le type Query, qui n'a pas ce champ. Demande à l'intérieur de order(id: 1042) { ... }.
  • Casser le corps JSON. Un guillemet double dans la requête, comme dans __type(name: "Order"), doit s'écrire \" ; sinon Express rejette le corps avec une page 400 avant que GraphQL ne le voie.
  • Essayer une autre commande. order(id: 1041) est refusée : le contrôle sur l'objet fonctionne. La fuite est un champ de ta propre commande.
  • Répondre avec le nom du champ, ou avec l'ancien code. La réponse est la valeur de agentOverrideCode ; le OVR-TEST-1188 dans agentNote a expiré.

Comment s'en protéger

Ferme la fuite et ajoute le contrôle manquant.

  • Masque les suggestions en production : new ApolloServer({ hideSchemaDetailsFromClientErrors: true }) (Apollo Server 4.11 et suivants), ou le plugin block-field-suggestions de graphql-armor sur les autres serveurs.
  • Autorise les champs, pas seulement les objets : donne aux champs réservés au staff leur propre contrôle de rôle dans le resolver (ou une directive d'authentification), ou sers le tableau de bord du support depuis un schéma séparé.
  • Considère quand même le schéma comme public : l'introspection coupée et les suggestions masquées ralentissent un attaquant, elles ne protègent pas les données. Pour tes propres clients, une allowlist de persisted queries bloque toute requête arbitraire.

Solution complète

Les membres Pro et Max débloquent la solution complète étape par étape.

Passer Pro

Statistiques de la communauté

126 résolutions
77% taux de réussite
M2F14M3 Premier sang

Hacks du jour associés

36 000+ Hackers Vrais labs Gratuit
Commencer Gratuitement ou résolvez le hack du jour, sans compte