Graphql Introspection in Actix with Bearer Tokens
Graphql Introspection in Actix with Bearer Tokens — how this specific combination creates or exposes the vulnerability
GraphQL introspection allows clients to query the schema, types, and operations of a GraphQL endpoint. When an Actix service exposes GraphQL without restricting introspection and also uses Bearer Tokens for authorization, a misconfiguration can expose both the API structure and sensitive operations to unauthenticated or low-privilege actors.
Introspection queries (e.g., __schema and __type) do not require authentication if the endpoint does not enforce it. In Actix, if the GraphQL handler is mounted under a route that does not validate the Authorization header before invoking the GraphQL resolver, an attacker can perform introspection even when Bearer Tokens are required for other operations. This reveals queries, mutations, and fields that should be opaque, effectively bypassing security-by-obscurity and enabling targeted attacks such as BOLA/IDOR or property authorization flaws.
When Bearer Tokens are validated after the GraphQL resolver in Actix middleware, introspection may still execute and leak schema details before the token is inspected. An attacker can craft introspection requests using common HTTP clients or GraphQL clients without providing a token, discovering operation names like resetPassword or exportUserData. These names, combined with field structures, provide actionable intelligence for crafting authenticated attacks once a token is compromised or brute-forced.
In a real Actix implementation using async-graphql or juniper, the introspection query can be sent as a POST with {"query": "__schema { queryType { name } }"}. If the Actix route does not reject unauthenticated requests before reaching the GraphQL service, the full schema is returned. This is particularly risky when the service also relies on Bearer Tokens to gate privileged mutations, because the token is not validated early enough to stop introspection.
To align with the OWASP API Top 10 and common compliance mappings (PCI-DSS, SOC2), GraphQL introspection should be disabled in production or restricted by authentication context. middleBrick scans detect such exposure by checking whether introspection is reachable without credentials and whether Bearer Token validation occurs before resolver execution, highlighting the need for early authorization checks in Actix middleware pipelines.
Bearer Tokens-Specific Remediation in Actix — concrete code fixes
Securing an Actix GraphQL endpoint that uses Bearer Tokens requires validating the token before invoking the GraphQL resolver and explicitly disabling introspection for unauthenticated requests. The following patterns demonstrate secure implementations.
1. Early Bearer Token validation in Actix middleware
Validate the Authorization header in an Actix extractor or middleware before routing to the GraphQL handler. This ensures introspection and other operations are rejected without a valid token.
use actix_web::{dev::ServiceRequest, Error, HttpMessage};
use actix_web_httpauth::extractors::bearer::BearerAuth;
use futures_util::future::{ok, Ready};
use std::task::{Context, Poll};
struct AuthenticatedRequest {
user: String,
}
impl actix_web::FromRequest for AuthenticatedRequest {
type Error = Error;
type Future = Ready<Result
Use AuthenticatedRequest as a guard on GraphQL routes to ensure introspection is only accessible to authenticated clients.
2. Disable introspection for unauthenticated requests in GraphQL configuration
If using async-graphql, configure the schema to conditionally disable introspection based on authentication state. This can be done by wrapping the schema creation and providing a custom Context that indicates whether introspection is allowed.
use async_graphql::{Context, Schema, EmptySubscription};
use async_graphql::http::GraphiQLSource;
struct MyQuery;
// Define your GraphQL objects and resolvers here
fn create_schema() -> Schema<MyQuery, EmptySubscription<()>> {
Schema::build(MyQuery, EmptySubscription, EmptySubscription).finish()
}
// In your Actix handler, you can conditionally disable introspection:
async fn graphql_handler(
req: actix_web::HttpRequest,
body: String,
auth: Result<AuthenticatedRequest, actix_web::Error>
) -> Result<actix_web::HttpResponse> {
let is_authenticated = auth.is_ok();
let schema = create_schema();
// async-graphql does not expose a built-in introspection toggle; implement a wrapper that rejects introspection queries when unauthenticated
if !is_authenticated && contains_introspection(&body) {
return Ok(actix_web::HttpResponse::Forbidden().body("Introspection not allowed without authentication"));
}
let request = GraphQLRequest::from(body);
let response = schema.execute(request).await;
Ok(actix_web::HttpResponse::Ok().json(response))
}
fn contains_introspection(body: &str) -> bool {
let query: serde_json::Value = serde_json::from_str(body).unwrap_or_default();
if let Some(query_str) = query["query"].as_str() {
query_str.contains("__schema") || query_str.contains("__type")
} else {
false
}
}
3. Example secure Actix route with Bearer Token and GraphQL
Combine the above patterns into a production-ready route that enforces authentication before executing any GraphQL operation, including introspection.
use actix_web::{web, App, HttpServer, HttpResponse};
async fn run_server() -> std::io::Result<()> {
HttpServer::new(|| {
App::new()
.route("/graphql", web::post().to(graphql_handler))
})
.bind("127.0.0.1:8080")?
.run()
.await
}
These fixes ensure that Bearer Tokens are validated early, introspection is restricted based on authentication, and the attack surface exposed by GraphQL metadata is minimized in Actix services.
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 |