MEDIUM graphql introspectionactix

Graphql Introspection in Actix

How Graphql Introspection Manifests in Actix

Graphql Introspection in Actix applications typically surfaces through default configuration settings that leave introspection endpoints exposed to unauthenticated users. In Actix Web applications using libraries like async-graphql-actix-web or juniper-actix, the introspection query is often enabled by default without proper access controls.

The most common manifestation occurs in the GraphQL handler setup where developers use the default playground or graphiql endpoints. These endpoints expose the full schema introspection query, allowing attackers to map the entire API surface without authentication. In Actix, this typically appears in route definitions like:

async fn graphql_handler(schema: web::Data, req: HttpRequest) -> HttpResponse {
    let res = schema.execute(req.into_inner()).await;
    HttpResponse::Ok().json(res)
}

Without proper middleware, this handler accepts any GraphQL query, including introspection queries that reveal:

  • Available object types and their fields
  • Input types and arguments
  • Enum values and directives
  • Database schema relationships
  • Internal business logic structure
  • Potential injection points

Actix-specific implementations often expose this through the graphql_playground route, which by default serves the full GraphQL IDE with introspection enabled. The vulnerability becomes more severe when combined with Actix's async execution model, as attackers can send concurrent introspection queries to map large schemas quickly.

Another Actix-specific pattern occurs when using actix-web-actors for GraphQL subscriptions. The WebSocket upgrade path for GraphQL subscriptions often inherits the same authentication bypass, exposing real-time data streams and subscription schemas to unauthenticated users.

Actix-Specific Detection

Detecting GraphQL introspection vulnerabilities in Actix applications requires examining both the route configuration and the GraphQL schema setup. Using middleBrick's API security scanner, you can identify these issues through its comprehensive GraphQL endpoint analysis.

middleBrick specifically tests for GraphQL introspection by sending the standard introspection query to your Actix endpoints:

query IntrospectionQuery {
  __schema {
    types {
      kind
      name
      fields {
        name
      }
    }
  }
}

The scanner checks whether this query succeeds without authentication, which indicates an exposed introspection endpoint. For Actix applications, middleBrick also examines:

  • Route definitions in lib.rs or main.rs for unprotected GraphQL handlers
  • Schema configuration files for default introspection settings
  • Middleware chains to verify authentication requirements
  • Playground and GraphiQL route configurations

Actix-specific detection also involves checking for common anti-patterns like:

// Vulnerable Actix pattern - no authentication middleware
let schema = Schema::new(Query, Mutation, Subscription);
HttpServer::new(move || {
    App::new()
        .app_data(web::Data::new(schema.clone()))
        .service(web::resource("/graphql").route(web::post().to(graphql_handler)))
        .service(web::resource("/playground").route(web::get().to(playground)))
}).bind("127.0.0.1:8080")?.run().await

middleBrick's detection engine identifies these patterns and provides specific remediation guidance for Actix applications, including recommended middleware configurations and schema protection strategies.

Actix-Specific Remediation

Securing GraphQL introspection in Actix applications requires a multi-layered approach that leverages Actix's middleware system and GraphQL library configuration. The most effective remediation combines authentication middleware with GraphQL schema protection.

First, implement authentication middleware at the Actix application level:

use actix_web::{middleware, web, App, HttpServer};
use actix_web_httpauth::middleware::HttpAuthentication;

async fn auth_middleware(
    req: HttpRequest,
    credentials: BasicAuth,
) -> Result {
    // Validate credentials
    if validate_user(credentials.user_id(), credentials.password()) {
        Ok(req)
    } else {
        Err(actix_web::error::ErrorUnauthorized("Invalid credentials"))
    }
}

let server = HttpServer::new(move || {
    App::new()
        .wrap(middleware::Logger::default())
        .wrap(HttpAuthentication::basic_async(auth_middleware))
        .app_data(web::Data::new(schema.clone()))
        .service(web::resource("/graphql").route(web::post().to(graphql_handler)))
        .service(web::resource("/playground").route(web::get().to(playground)))
});

Second, configure your GraphQL schema to disable introspection in production:

use async_graphql::{Schema, EmptyMutation, EmptySubscription};

let schema = Schema::build(QueryRoot, EmptyMutation, EmptySubscription)
    .disable_introspection(!is_production()) // Disable in production
    .finish();

// Or use a custom directive to control introspection access
#[async_graphql::Object]
impl QueryRoot {
    #[field(guard(Authenticated))]
    async fn protected_data(&self) -> String {
        "Sensitive information".to_string()
    }
}

For Actix-specific WebSocket subscriptions, add authentication to the upgrade path:

async fn graphql_ws_handler(schema: web::Data, req: HttpRequest, payload: web::Payload) -> Result {
    // Authenticate WebSocket connection
    if !is_authenticated(req.headers()) {
        return Ok(HttpResponse::Unauthorized().finish());
    }
    
    graphql_ws(schema, &req, payload).await
}

Additionally, implement rate limiting and query cost analysis to prevent abuse even if introspection is partially exposed:

use actix_web::middleware::NormalizePath;
use actix_ratelimit::RateLimiter;

let app = App::new()
    .wrap(NormalizePath)
    .wrap(RateLimiter::default())
    .service(web::resource("/graphql").route(web::post().to(graphql_handler)));

These Actix-specific remediation strategies provide comprehensive protection against GraphQL introspection attacks while maintaining legitimate development and debugging capabilities.

Related CWEs: dataExposure

CWE IDNameSeverity
CWE-200Exposure of Sensitive Information HIGH
CWE-209Error Information Disclosure MEDIUM
CWE-213Exposure of Sensitive Information Due to Incompatible Policies HIGH
CWE-215Insertion of Sensitive Information Into Debugging Code MEDIUM
CWE-312Cleartext Storage of Sensitive Information HIGH
CWE-359Exposure of Private Personal Information (PII) HIGH
CWE-522Insufficiently Protected Credentials CRITICAL
CWE-532Insertion of Sensitive Information into Log File MEDIUM
CWE-538Insertion of Sensitive Information into Externally-Accessible File HIGH
CWE-540Inclusion of Sensitive Information in Source Code HIGH

Frequently Asked Questions

Can I completely disable GraphQL introspection in Actix?
Yes, using async-graphql's disable_introspection method or configuring your schema to reject introspection queries. However, completely disabling introspection can make development and debugging more difficult, so consider using environment-based configuration to enable it only in development.
How does middleBrick detect GraphQL introspection in Actix applications?
middleBrick sends a standard GraphQL introspection query to your Actix endpoints and analyzes the response. It checks if the query succeeds without authentication, examines the returned schema structure, and identifies unprotected GraphQL routes in your Actix application configuration.