Contournement de la protection anti-brute-force en GraphQL

Bypassing GraphQL brute force protections

Contexte du lab

Le formulaire de connexion du lab s’appuie sur une API GraphQL avec un rate limiter : après plusieurs tentatives incorrectes, l’endpoint renvoie une erreur indiquant qu’il faut attendre (ex. 1 minute) avant de réessayer.

Objectif : bruteforcer le login pour se connecter en tant que carlos, en utilisant la liste de mots de passe fournie par les labs d’authentification.

1) Observation de la requête GraphQL

En interceptant la connexion, on récupère une mutation du type :

Après trop d’essais incorrects, l’API répond par une erreur de limitation :

2) Pourquoi “multiplier les champs” ne marche pas tel quel

Une idée naturelle est d’envoyer plusieurs appels login dans une seule mutation.

chevron-rightAuthentication lab passwordsarrow-up-righthashtag

123456 password 12345678 qwerty 123456789 12345 1234 111111 1234567 dragon 123123 baseball abc123 football monkey letmein shadow master 666666 qwertyuiop 123321 mustang 1234567890 michael 654321 superman 1qaz2wsx 7777777 121212 000000 qazwsx 123qwe killer trustno1 jordan jennifer zxcvbnm asdfgh hunter buster soccer harley batman andrew tigger sunshine iloveyou 2000 charlie robert thomas hockey ranger daniel starwars klaster 112233 george computer michelle jessica pepper 1111 zxcvbn 555555 11111111 131313 freedom 777777 pass maggie 159753 aaaaaa ginger princess joshua cheese amanda summer love ashley nicole chelsea biteme matthew access yankees 987654321 dallas austin thunder taylor matrix mobilemail mom monitor monitoring montana moon moscow

Mais si on répète le même champ sans distinction, GraphQL le refuse car les champs seraient ambigus (même nom au même niveau).

Exemple non valide (structure incorrecte / collision de champs) :

3) Contournement : utiliser des aliases

GraphQL permet de renommer chaque appel grâce aux aliases. Ainsi, on peut exécuter plusieurs tentatives de login dans une seule requête HTTP, ce qui réduit l’impact du rate limit “par requête”.

Exemple valide :

Résultat : l’API traite plusieurs essais en une seule “fenêtre” côté rate limiter.

4) Automatisation (approche script)

Principe :

  • Construire mutation login { ... }

  • Ajouter une ligne par mot de passe :

    • login{i}: login(input: { username: "carlos", password: "..." }) { token success }

  • Envoyer la requête

  • Parcourir la réponse data.login{i} pour trouver success: true

Le mot de passe trouvé pour carlos est :

Mis à jour