Aller au contenu

Brute Force Login Using Alias Batching in GraphQL API

Attaque par force brute de connexion utilisant le traitement par lots d'alias dans l'API GraphQL

Description

Une attaque par force brute via des requêtes par lots utilisant des alias dans GraphQL implique qu'un attaquant exploite la fonctionnalité d'alias pour automatiser les tentatives de connexion, ce qui facilite la soumission de nombreuses combinaisons d'identifiants dans une seule requête.

Dans GraphQL, les alias permettent aux clients d'envoyer plusieurs versions de la même requête sous des noms différents. Les attaquants exploitent cela en regroupant les requêtes de connexion au sein d'une seule requête HTTP à l'aide de différents noms d'alias pour chaque tentative. Cela peut conduire à une attaque par force brute efficace, contournant les protections traditionnelles de limitation de débit (rate limiting) et submergeant le système d'authentification de tentatives de connexion.

Exemple :

query loginBatch {
  login1: login(username: "user1", password: "password1") { token }
  login2: login(username: "user2", password: "password2") { token }
  login3: login(username: "user3", password: "password3") { token }
  ...
}

Recommandation

Pour atténuer les risques d'attaques par force brute utilisant des lots d'alias, envisagez de mettre en œuvre les mesures suivantes :

  • Limiter les alias : Configurez des limites côté serveur sur le nombre d'alias autorisés dans une seule requête GraphQL. Vous pouvez configurer des outils comme GraphQL Armor pour limiter les alias et éviter les surcharges.

  • Implémenter un CAPTCHA : Introduisez un CAPTCHA ou d'autres mécanismes de vérification de l'utilisateur pour tester les utilisateurs après un certain nombre de tentatives de connexion infructueuses, ajoutant ainsi une couche de protection supplémentaire.

  // Configuring rate limiting and alias limits for a GraphQL server
  const express = require('express');
  const rateLimit = require('express-rate-limit');
  const { ApolloServer, gql } = require('apollo-server-express');
  const { GraphQLArmorConfig } = require('graphql-armor');

  const app = express();

  // Rate limit for login attempts
  const loginLimiter = rateLimit({
    windowMs: 15 * 60 * 1000, // 15 minutes
    max: 5, // limit each IP to 5 requests per windowMs
    message: "Too many login attempts, please try again later."
  });

  // Define your GraphQL schema
  const typeDefs = gql`
    type Query {
      login(username: String!, password: String!): String
    }
  `;

  // Implement the alias limit configuration
  GraphQLArmorConfig({
    maxAliases: {
      enabled: true,
      n: 20, // Set the maximum number of aliases allowed per query
      onAccept: [],
      onReject: [],
      propagateOnRejection: true,
    }
  });

  const server = new ApolloServer({ typeDefs, resolvers });

  // Apply rate limiter middleware
  app.use('/graphql', loginLimiter);

  server.applyMiddleware({ app });

  app.listen({ port: 4000 }, () =>
    console.log(`Server ready at http://localhost:4000${server.graphqlPath}`)
  );
  import graphql
  from graphql.language import ast
  from graphql.language import parser
  from settings import api

  def validate_aliases(query: str) -> None:
      """
      This validation prevents the execution of queries containing an excessive
      number of aliases to prevent server overload.
      """
      class AliasesParser(parser.Parser):
          def parse_aliases(self) -> list[ast.FieldNode]:
              aliases = 0
              while self.peek(graphql.TokenKind.NAME):
                  aliases += 1
                  if aliases > api.API_MAX_ALIASES:
                      raise graphql.GraphQLError("Exception - Max aliases exceeded")
                  self.parse_field()
              return []

      ast_parser = AliasesParser(query)
      ast_parser.parse_document()

Liens

Normes

  • PCI_STANDARDS:
    • REQ_6_2
    • REQ_6_4
    • REQ_11_3
  • OWASP_ASVS_L3:
    • V13_4_1
  • SOC2_CONTROLS:
    • CC_2_1
    • CC_4_1
    • CC_7_1
    • CC_7_2
    • CC_7_4
    • CC_7_5
    • CC_9_1
  • HIPAA_CONTROLS:
    • SECURITY221
    • SECURITY212
    • SECURITY213