HIGH graphql introspectionactixbasic auth

Graphql Introspection in Actix with Basic Auth

Graphql Introspection in Actix with Basic Auth — how this specific combination creates or exposes the vulnerability

GraphQL introspection is a query capability that returns the full schema, including types, queries, and mutations. When used unintentionally in production, it can expose implementation details that aid attackers. In Actix web applications, GraphQL endpoints often rely on middleware or guards to enforce authentication. If introspection is allowed without proper access controls, and the service uses Basic Authentication, the combination can unintentionally expose the schema to unauthenticated or partially authenticated clients.

Basic Auth in Actix is typically implemented by inspecting the Authorization header on each request. If the GraphQL handler does not explicitly reject introspection queries for requests that lack valid credentials, the endpoint may return schema data even when the request carries only an invalid or missing Basic Auth token. Because introspection queries are standard GraphQL operations, they are processed like any other query unless the server explicitly blocks them.

This becomes a security risk when the GraphQL endpoint is publicly reachable but Basic Auth is assumed to be sufficient protection. Attackers can send introspection queries to the same endpoint used by authenticated clients, and if the server does not differentiate between authenticated and unauthenticated introspection requests, they obtain a detailed map of the API. That map can reveal query names, input structures, and potential data exposure paths that are useful for further exploitation, such as IDOR or injection attacks.

middleBrick detects this class of issue as part of its Unauthenticated endpoint and Input Validation checks. During a scan, if introspection is accessible without valid credentials, the scanner reports the finding with severity and guidance. The scanner also cross-references the OpenAPI/Swagger specification, if available, to see whether introspection is documented or restricted, and compares that with runtime behavior to reduce false positives.

Remediation guidance focuses on ensuring introspection is disabled or properly gated behind authentication, and that the server does not leak schema details in error responses. The scanner does not fix the code but provides prioritized findings and actionable remediation steps, helping teams secure the endpoint without relying on assumptions about which methods should be public.

Basic Auth-Specific Remediation in Actix — concrete code fixes

Securing GraphQL introspection in Actix with Basic Auth requires explicit checks before allowing the introspection operation. Below are concrete code examples that demonstrate how to implement authentication and disable introspection for unauthenticated requests.

First, a Basic Auth extractor can be implemented using Actix's built-in guards and extractors. The following example shows a custom guard that validates a username and password against expected values:

use actix_web::{web, HttpRequest, Error};
use actix_web::http::header::HeaderValue;
use actix_web::dev::ServiceRequest;
use actix_web::error::ErrorUnauthorized;
use actix_web::http::header::AUTHORIZATION;
use base64::decode;

async fn validate_basic_auth(req: &ServiceRequest) -> Result<(), Error> {
    let headers = req.headers();
    if let Some(auth_header) = headers.get(AUTHORIZATION) {
        if let Ok(auth_str) = auth_header.to_str() {
            if auth_str.starts_with("Basic ") {
                let encoded = &auth_str[6..];
                if let Ok(decoded) = decode(encoded) {
                    if let Ok(credentials) = String::from_utf8(decoded) {
                        let parts: Vec<&str> = credentials.split(':').collect();
                        if parts.len() == 2 && parts[0] == "admin" && parts[1] == "secret" {
                            return Ok(());
                        }
                    }
                }
            }
        }
    }
    Err(ErrorUnauthorized("Invalid authentication"))
}

This extractor can then be applied to the GraphQL route to ensure that only requests with valid credentials are processed. You can also disable introspection entirely by configuring the GraphQL endpoint to reject introspection queries:

use actix_web::web;
use actix_web_graphql::{GraphQLRequest, GraphQLResponse};
use async_graphql::Schema;

async fn graphql_handler(
    schema: web::Data>,
    req: GraphQLRequest,
) -> GraphQLResponse {
    let query = req.query;
    if query.trim().to_lowercase().starts_with("__schema") || query.trim().to_lowercase().starts_with("__type") {
        return GraphQLResponse::from_error("Introspection is not allowed".into());
    }
    schema.execute(query).await.into()
}

For applications that require introspection for internal tooling but not for public access, combine the authentication guard with conditional logic that allows introspection only for authenticated requests. The following snippet demonstrates this approach by validating credentials first and then selectively permitting introspection operations:

async fn guarded_graphql_handler(
    schema: web::Data>,
    req: GraphQLRequest,
    auth_req: web::ReqGuard<()>, // validated by prior guard
) -> GraphQLResponse {
    let query = req.query;
    if query.trim().to_lowercase().starts_with("__schema") || query.trim().to_lowercase().starts_with("__type") {
        if auth_req.identity().is_some() {
            return schema.execute(query).await.into();
        } else {
            return GraphQLResponse::from_error("Introspection requires authentication".into());
        }
    }
    schema.execute(query).await.into()
}

These patterns ensure that introspection is not inadvertently exposed when using Basic Auth. By explicitly checking credentials and query content, you reduce the risk of schema disclosure through the GraphQL endpoint.

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 GraphQL introspection be safely enabled if Basic Auth is used?
It can be enabled for authenticated requests, but it should be blocked for unauthenticated requests. Always validate credentials before allowing introspection to prevent public schema disclosure.
How does middleBrick detect GraphQL introspection exposure in Actix services?
middleBrick sends introspection queries to the endpoint and checks whether schema data is returned without valid authentication. It compares the runtime behavior against any provided OpenAPI/Swagger definitions to confirm findings.