API GraphQL

Riepilogo:
GraphQL is a query language for APIs that was created by Facebook in 2012 and open sourced in 2015. It provides an alternative to REST APIs and enables developers to request exactly the data they need from an API. While GraphQL offers many benefits over traditional REST APIs, like improved performance and developer experience, it also introduces new potential vulnerabilities that developers need to be aware of when designing and securing GraphQL APIs. In this comprehensive guide, we will explore the most common GraphQL vulnerabilities, how they can be exploited, and how to properly secure GraphQL APIs against attacks.

What is GraphQL?

GraphQL is a strongly-typed query language that allows clients to request precisely the data they need from an API. It replaces the typical collections of REST endpoints with a single endpoint that accepts queries.

A GraphQL query is used to retrieve data from a GraphQL schema. The schema defines the structure of an API and the relationships between different entities. It specifies the types of data that can be queried as well as the operations for querying and manipulating that data.

Some key advantages of GraphQL include:

  • Flexibility – Clients can request only the data they need, avoiding over and under fetching issues common with REST.
  • Type safety – The GraphQL schema defines types for API data, enabling early detection of errors.
  • Hierarchical – GraphQL structures APIs as graphs of data, mirroring how apps use data.
  • Efficient – Clients can reduce API requests by fetching more data in a single call.
  • Developer experience – GraphQL APIs are self-documenting and easy for developers to consume.
  • Evolvable – GraphQL schemas can be added to without impacting existing queries.

Common GraphQL Vulnerabilities

While GraphQL introduces many benefits, it also comes with its own unique security challenges. Some common GraphQL vulnerabilities include:

  • Broken Authentication and Access Controls
  • Server Side Request Forgery (SSRF)
  • Denial of Service
  • Introspection Query Information Leaks
  • Injection Attacks
  • Rate Limit Bypass

We will cover each of these common vulnerabilities in more detail below.

Broken Authentication and Access Controls

Proper authentication and authorization needs to be implemented when designing a GraphQL API, just like with a REST API. Some common issues include:

  • Failing to protect resolvers: Resolvers in GraphQL fulfill a similar role to controllers in a REST API. They contain the application logic and handle fetching data from databases and other back end systems. Resolvers need proper access controls to prevent data exposure.
  • Non-protected schemas: The GraphQL schema defines what queries can be executed against the API. It needs proper access controls to prevent anonymous users from querying sensitive data types and fields.
  • Leaked authorization rules: The GraphQL schema type system specifies what types a user can query and mutate. This inherently leaks some authorization rules that need to be protected.
  • Overly permissive queries: GraphQL queries allow filtering of fields within a type. Access controls need to be applied at the field level to prevent data exposure.

These issues can allow attackers to access unauthorized data or perform privileged actions. Proper authorization should be applied in GraphQL resolvers, schemas, and query analyzers.

Server Side Request Forgery (SSRF)

GraphQL APIs often need to interact with internal systems and external services to gather data to fulfill queries. For example, a GraphQL API may call out to internal databases or microservices. Improperly configured resolvers can lead to server-side request forgery (SSRF) vulnerabilities.

Attackers can potentially abuse insecure resolver logic to interact with internal systems or external sites like AWS metadata services. This can lead to unauthorized data access or denial of service.

Extra caution needs to be taken when allowing user input for fields like URLs or IPs that resolvers use to call out to other systems. Whitelists should be used to restrict allowed destinations.

Denial of Service

The flexibility of GraphQL queries can enable denial of service attacks in a few different ways:

  • Overly complex queries: GraphQL APIs can potentially accept complex nested queries. These queries can overload backend systems.
  • Resource intensive queries: Attackers can craft queries that target expensive database operations or trigger complex computations in resolvers.
  • Bulk requests: GraphQL allows multiple queries in a single request. Attackers can use this to overwhelm servers.

Limits should be imposed on queries to prevent denial of service attacks:

  • Query depth limits
  • Computational complexity thresholds
  • Rate limiting.

Backend systems also need proper resource management to gracefully handle spikes in traffic volume.

Introspection Query Information Leaks

The GraphQL introspection system allows querying an API for information about its schema and the available types, fields, arguments, and more. This is intended to enable developers to understand how to properly interact with the API.

However, introspection queries can leak sensitive information in production environments like:

  • Structure of the backend server
  • Internal architecture details
  • Comments with potential secrets or sensitive information
  • Hidden fields and arguments that attackers could potentially access

Introspection should be disabled in production. If it’s needed for public APIs, sensitive fields should be excluded from introspection results.

Injection Attacks

User-supplied input needs to always be properly sanitized and validated to prevent injection attacks, including GraphQL APIs. Some potential injection attack vectors include:

  • SQL injection if queries are built unsafely from user input
  • Code injection if exploitable vulnerabilities exist in underlying frameworks and libraries
  • GraphQL-specific attacks like stitching attack vectors together via aliases

The strong typing in GraphQL prevents some traditional injection attacks but input still needs proper encoding, sanitization, and validation before being passed to resolvers.

User input should be sanitized as early as possible, like when initially entering the GraphQL server code. Encoding, validation, and sanitization should also occur in resolvers. Context variables can assist in safely passing user input to resolvers.

Exploiting GraphQL APIs

GraphQL is a query language that provides an alternative to REST for building APIs. It offers many benefits, including improved performance, developer experience, and the ability to evolve APIs over time. However, GraphQL also introduces new security considerations compared to REST. In this comprehensive guide, we will explore common GraphQL vulnerabilities, including code examples of exploits and how to properly defend GraphQL APIs against them.

Just like any API that accepts user input, GraphQL endpoints are susceptible to injection attacks if improper input validation and sanitization is performed. Some common GraphQL injection risks include:

Exploiting GraphQL: Code Injection

If GraphQL queries are constructed unsafely from user input, code injection is possible in vulnerable GraphQL servers, frameworks or libraries:

# User input:

query {
 books(filter: '); require("child_process").exec("calc.exe"); -- ') {
   id
   name
 }
}

# Constructed query:

{
 books(filter: '); require("child_process").exec("calc.exe"); -- ') {
   id
   name
 }
}

This code injection attack leverages the user input to execute arbitrary system commands.

Exploiting GraphQL: SQL Injection

If the GraphQL API interacts with a SQL database, SQL injection is possible via unsafe construction of queries:

# User input:

query {
 users(filter: "' OR 1=1 --") {
   id
   name
 }
}

# Constructed query:

SELECT id, name
FROM users
WHERE filter = '' OR 1=1 --'

The user input injects a tautology to return all users.

To prevent injection attacks:

  • Use prepared statements and query builders
  • Convalida e disinfetta tutti gli input dell'utente
  • Implementa una whitelist per campi speciali come filter
  • Esegui politiche CORS restrittive sugli endpoint GraphQL

Autenticazione e autorizzazione GraphQL non funzionanti

È necessario implementare l'autenticazione e l'autorizzazione corretta per proteggere le API GraphQL. Alcune vulnerabilità comuni includono:

Resolver non protetti

I resolver si comportano in modo simile ai controller nelle API REST. Eseguono la logica di backend e restituiscono i dati. Le autorizzazioni devono essere verificate nei resolver:

//Risolutore senza controllo di autenticazione
const getUsers = () => {
restituisce user.find ();
}

//Resolver sicuro
const getUsers = (genitore, args, contesto) => {
Stati Uniti (! contesto. è autenticato () {
genera un nuovo errore («Non autenticato»);
}
restituisce user.find ();
}

Regole di autorizzazione trapelate

Il sistema di tipi di schema GraphQL rivela intrinsecamente alcune regole di autenticazione. Ad esempio, la visibilità dei tipi e dei campi rivela se l'utente corrente può interrogarli o meno.

Interrogazioni eccessivamente permissive

È possibile richiedere campi specifici all'interno di un tipo GraphQL. Le autorizzazioni devono essere definite a livello di campo:

tipo di utente {
ID: ID
nome: String
email: String # Non deve essere annullabile per gli utenti autorizzati
}

interrogazione digitale {
utente (id: ID): Utente
}

Per proteggere correttamente l'autenticazione e l'autorizzazione:

  • Usa token o sessioni Web JSON per gestire l'autenticazione
  • Implementa il controllo degli accessi basato sui ruoli
  • Limita le domande di introspezione
  • Proteggi i resolver con controlli di autenticazione granulari
  • Aggiungi asserzioni non nulle ai campi nello schema GraphQL per gli utenti autorizzati

Esempio di negazione del servizio in GraphQL

La flessibilità di GraphQL consente attacchi denial of service attraverso:

  • Interrogazioni annidate complesse
  • Interrogazione destinata a costose operazioni di database
  • Calcoli ad alta intensità di risorse nei resolver
  • Operazioni in blocco tramite alias

Implementa i limiti di complessità delle query per prevenire gli attacchi DoS:

const {apolloServer} = richiedi ('apollo-server');

const server = nuovo ApolloServer ({
schema,
Regole di convalida: [
Complessità della query ({
//Imposta la complessità massima delle query
Complessità massima: 1000
})
]
});

Le strategie aggiuntive includono:

  • Limitazione della profondità massima delle interrogazioni
  • Litica del numero di alias
  • Analisi dei costi degli interrogatori
  • Limite del tempo totale di esecuzione della query

Assicurati che i sistemi di backend come i database siano in grado di gestire i picchi di traffico con garbo.

Falsificazione delle richieste lato server (SSRF)

Se i resolver GraphQL interagiscono con servizi interni o esterni, SSRF è possibile:

const getRepoDetails = async (RepoName) => {

const url = `https://api.github.com/repos/${repoName}`;

risposta const = aspetta axios.get (url);

restituire i dati della risposta;

};

Se repoName proviene dall'input dell'utente, un utente malintenzionato potrebbe forzare le richieste ai servizi interni.

Per prevenire l'SSRF:

  • Convalida e disinfetta gli input degli utenti, in particolare gli URL/IP
  • Implementa una whitelist per i servizi di terze parti che possono essere richiesti
  • Limita le porte/i protocolli a cui è possibile accedere

Perdita di informazioni tramite introspezione

L'introspezione GraphQL fornisce dettagli sullo schema, inclusi tipi, campi, argomenti e descrizioni.

L'introspezione dovrebbe essere disattivata in produzione. Se necessario, i campi sensibili devono essere esclusi.

const TypeDefs = gql`

interrogazione digitale {
utenti: [Utente!]!
}

tipo di utente {
ID: ID!
nome: String!
# Escludi le email dall'introspezione
email: String!
}
`;

const server = nuovo ApolloServer ({
schema,
introspezione: true, //Disabilita per la produzione

//Escludi le email dall'introspezione
estensioni: ({context}) => {
if (context.excludeIntrospection) {
ritorno {
redatto: ['user.email']
}
}
}
});

L'estensione di redazione nasconde i campi sensibili.

GraphQL fornisce un'alternativa flessibile alle API REST. Tuttavia, è necessario tenere conto di considerazioni di sicurezza uniche. Le vulnerabilità comuni legate all'iniezione, all'autenticazione, alla negazione del servizio e alla divulgazione di informazioni possono mettere a rischio i consumatori di API e i sistemi di backend. Implementando correttamente l'autenticazione, l'autorizzazione, la convalida degli input, i limiti di complessità delle query e disabilitando l'introspezione, le aziende possono sfruttare in modo sicuro GraphQL per fornire funzionalità API di nuova generazione.

Bypass del limite di velocità

Le API utilizzano in genere la limitazione della velocità per prevenire attacchi di forza bruta o denial of service. In GraphQL, i clienti possono aggirare i limiti di velocità standard distribuendo le operazioni tra alias in un'unica richiesta.

Ad esempio, normalmente un limite di velocità può consentire 10 richieste al minuto. Ma una singola richiesta GraphQL potrebbe eseguire 100 o più operazioni tramite aliasing.

Le strategie per prevenire il bypass dei limiti di velocità includono:

  • Limiti per l'operazione
  • Lítica del numero de alias
  • Analisi della complessità delle domande in arrivo
  • Limiti di profondità delle interrogazioni

Protezione corretta delle API GraphQL

Ecco alcune best practice da seguire per proteggere le API GraphQL:

Autenticazione e autorizzazione

  • Implementa un'autenticazione corretta come JWT per identificare i consumatori di API.
  • Sfrutta il controllo degli accessi basato sui ruoli per limitare le autorizzazioni.
  • Apply the autorizzazione nei resolver, negli schemi e negli analizzatori di interrogazione.
  • Limita l'introspezione negli ambienti di produzione.

Gestione degli input

  • Disinfetta e codifica l'input dell'utente il prima possibile.
  • Verifica che l'input dell'utente soddisfi i requisiti.
  • Usa il contesto GraphQL per passare l'input ai resolver.
  • Imposta una whitelist per campi speciali come URL e IP.

Limiti di complessità delle interrogazioni

  • Imposta la profondità massima consentita per le interrogazioni.
  • Limita il numero di campi e alias per richiesta.
  • Impiegare soglie di complessità computazionale.
  • Abilita l'analisi automatica dei costi delle interrogazioni.

Limiento de la velocità

  • Applica i limiti di velocità per operazione anziché per richiesta.
  • Limita il numero di alias univoci.
  • Imposta il numero massimo di byte per richiesta.

Registrazione e monitoraggio

  • Registra metriche chiave come latenza, errori e traffico.
  • Usa la traccia per monitorare l'esecuzione e le prestazioni del resolver.
  • Imposta avvisi per errori imprevisti e picchi di traffico.
  • Esegui regolarmente test di sicurezza Abbiamo verificato.

Suggerimenti aggiuntivi per la sicurezza

  • Segui il principio del privilegio minimo nella progettazione dello schema.
  • Disabilita il parco giochi GraphQL in produzione.
  • Convalida i tipi di contenuto sulle richieste.
  • Implementa il token CSRF.
  • Abilita CORS se necessario.
  • Maschera gli errori per non esporre gli interni.
  • Segui le migliori pratiche di sicurezza per i framework sottostanti.

Conclusione

GraphQL fornisce un'alternativa flessibile ed efficiente alle API REST. Tuttavia, è necessario tenere conto di considerazioni di sicurezza uniche durante la progettazione, l'implementazione e la protezione delle API GraphQL. Vulnerabilità comuni come autenticazione/autorizzazione non funzionanti, attacchi di iniezione, denial of service e fughe di informazioni possono mettere a rischio i consumatori di API e i sistemi di backend.

Seguendo le migliori pratiche di sicurezza in materia di autenticazione, controllo degli accessi, gestione della complessità delle query, convalida degli input e limitazione della velocità, le aziende possono sfruttare in modo sicuro i vantaggi delle API GraphQL. È inoltre necessario implementare strumenti e processi adeguati per il monitoraggio, la registrazione e il test. Con le dovute precauzioni prese dal team di sviluppo, GraphQL può essere sfruttato in modo sicuro per fornire funzionalità API di nuova generazione.

Pronti a vedere di persona?

Prova tu stesso tutte le funzionalità della piattaforma. Nessun impegno e nessuna carta di credito!

Prenota una demo
Prenota una demo