HIGH graphql introspectionfastapihmac signatures

Graphql Introspection in Fastapi with Hmac Signatures

Graphql Introspection in Fastapi with Hmac Signatures — how this specific combination creates or exposes the vulnerability

GraphQL introspection in a FastAPI service that uses HMAC signatures can expose the API surface even when authentication is enforced, because introspection queries are typically processed before signature validation is applied to the operation. An attacker can send a standard introspection request to the GraphQL endpoint and learn the full schema, including types, queries, and mutations, which may reveal sensitive business logic or hidden endpoints.

When HMAC signatures are implemented as a middleware or header check, they often validate the request after the GraphQL resolver pipeline has already begun. If introspection is allowed for unauthenticated or partially authenticated requests, the detailed schema returned can aid in crafting further attacks, such as IDOR or BOLA, by exposing query patterns and required fields. The combination therefore creates a risk where the very mechanism intended to verify request integrity (HMAC) does not restrict the introspection feature, allowing information leakage that would otherwise be protected.

In FastAPI, if the GraphQL route is defined without early rejection of introspection for unverified requests, the response includes type definitions and query relationships. This can be particularly dangerous when the API is exposed to unauthenticated scanning tools, because introspection can be run at any time to map the attack surface. HMAC signatures that only verify integrity of known operations do not inherently block introspection unless explicitly enforced at the route or schema level.

To illustrate, consider a FastAPI route that accepts POST JSON with a signature header but does not validate the presence or correctness of the signature before invoking the GraphQL handler. An attacker can send:

POST /graphql
Content-Type: application/json
{ "query": "{ __schema { queryType { name } } }"}

and receive a full schema in response if introspection is permitted. The HMAC signature, if checked later, does not prevent this disclosure. This highlights the need to treat introspection as a privileged operation and align it with the security assumptions behind HMAC verification.

Hmac Signatures-Specific Remediation in Fastapi — concrete code fixes

To secure GraphQL introspection alongside HMAC signatures in FastAPI, enforce signature validation before the GraphQL resolver runs and explicitly disable introspection for requests that cannot be verified. Below are concrete code examples showing how to implement HMAC verification and restrict introspection in a FastAPI application.

First, implement an HMAC verification dependency that checks a shared secret and a timestamp to prevent replay attacks:

import hmac
import hashlib
import time
from fastapi import Depends, HTTPException, Header, FastAPI
from pydantic import BaseModel
from typing import Optional

SECRET_KEY = b"your-secure-secret"
TIME_TOLERANCE = 30  # seconds

class GraphQLRequest(BaseModel):
    query: str
    variables: Optional[dict] = None

def verify_hmac(x_signature: str = Header(...), timestamp: str = Header(...)):
    # Prevent replay attacks by checking timestamp
    try:
        ts = int(timestamp)
    except ValueError:
        raise HTTPException(status_code=400, detail="Invalid timestamp")
    if abs(time.time() - ts) > TIME_TOLERANCE:
        raise HTTPException(status_code=401, detail="Request expired")
    body = GraphQLRequest  # In practice, you would read the raw body carefully
    # Note: In real usage, read raw request body for HMAC calculation
    # This is a simplified example
    signature = x_signature
    computed = hmac.new(SECRET_KEY, msg=signature.encode(), digestmod=hashlib.sha256).hexdigest()
    if not hmac.compare_digest(computed, signature):
        raise HTTPException(status_code=401, detail="Invalid signature")
    return True

Next, configure the GraphQL endpoint to require this dependency and disable introspection when verification is not applied. If you use a library such as strawberry or graphene with FastAPI, wrap the route so that introspection is only allowed when the HMAC check passes:

from fastapi import FastAPI, Depends
from starlette.responses import JSONResponse

app = FastAPI()

@app.post("/graphql")
async def graphql_endpoint(
    data: GraphQLRequest,
    _: bool = Depends(verify_hmac)
):
    # Here, integrate with your GraphQL library
    # For example, using a function that handles query execution
    # Ensure that introspection queries are rejected when not explicitly allowed
    if "__schema" in data.query or "__type" in data.query:
        raise HTTPException(status_code=403, detail="Introspection is not allowed")
    # Proceed with query execution
    return JSONResponse({"data": {}})

Alternatively, if you allow introspection for authenticated or verified requests only, add logic to inspect the HMAC validity and the request context before permitting introspection. This ensures that schema exposure is gated behind the same integrity checks used for other operations.

Finally, consider rotating the HMAC secret periodically and storing it securely, such as in environment variables or a secrets manager. Combine this with rate limiting to reduce the impact of brute-force attempts against the signature validation. These steps reduce the exposure of GraphQL metadata while preserving the integrity guarantees provided by HMAC signatures.

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 introspection be allowed for certain trusted queries while still using HMAC signatures in FastAPI?
Yes, you can allow introspection selectively by implementing a custom rule in your GraphQL server that checks the HMAC dependency and additional context (such as a header or role) before resolving introspection queries. Ensure that the decision logic is evaluated before returning schema details.
Does disabling introspection break legitimate API consumers who rely on schema discovery?
Disabling public introspection reduces attack surface. For legitimate consumers, provide an authenticated route or an internal tool that performs introspection under verified HMAC conditions, or share an OpenAPI-compatible description through a separate, well-controlled channel.