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.rsormain.rsfor 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 ID | Name | Severity |
|---|---|---|
| CWE-200 | Exposure of Sensitive Information | HIGH |
| CWE-209 | Error Information Disclosure | MEDIUM |
| CWE-213 | Exposure of Sensitive Information Due to Incompatible Policies | HIGH |
| CWE-215 | Insertion of Sensitive Information Into Debugging Code | MEDIUM |
| CWE-312 | Cleartext Storage of Sensitive Information | HIGH |
| CWE-359 | Exposure of Private Personal Information (PII) | HIGH |
| CWE-522 | Insufficiently Protected Credentials | CRITICAL |
| CWE-532 | Insertion of Sensitive Information into Log File | MEDIUM |
| CWE-538 | Insertion of Sensitive Information into Externally-Accessible File | HIGH |
| CWE-540 | Inclusion of Sensitive Information in Source Code | HIGH |
Frequently Asked Questions
Can I completely disable GraphQL introspection in Actix?
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.