Graphql Introspection on Azure
How Graphql Introspection Manifests in Azure
GraphQL introspection in Azure environments typically exposes detailed schema information through the /graphql endpoint when the introspection field is enabled in the GraphQL server configuration. This manifests as a POST request to your Azure-hosted GraphQL API with a query like:
query IntrospectionQuery {
__schema {
types {
kind
name
description
fields {
name
description
args {
name
description
type {
name
kind
}
}
type {
name
kind
}
}
}
}
}
In Azure App Service or Azure Functions, this vulnerability often appears when developers use Apollo Server, Hot Chocolate, or other GraphQL libraries without disabling introspection in production. The Azure-specific manifestation includes:
- Azure Functions with GraphQL endpoints exposing full schema via HTTP triggers
- Azure App Service running GraphQL servers with default introspection enabled
- Azure Container Instances hosting GraphQL services with public introspection endpoints
- Azure API Management gateways proxying GraphQL APIs without introspection controls
The attack surface expands in Azure because many developers deploy GraphQL services as part of microservices architectures, where one compromised service can lead to lateral movement. An attacker can use the exposed schema to craft targeted queries for data exfiltration, such as extracting all user records or payment information through GraphQL's flexible query capabilities.
Azure-Specific Detection
Detecting GraphQL introspection in Azure environments requires both network-level scanning and application-level inspection. Using middleBrick's Azure-specific scanning capabilities, you can identify exposed introspection endpoints across your Azure infrastructure:
# Install middleBrick CLI
npm install -g middlebrick
# Scan Azure-hosted GraphQL endpoint
middlebrick scan https://yourapi.azurewebsites.net/graphql --output json
middleBrick tests for GraphQL introspection by sending the standard introspection query and analyzing the response structure. The scanner identifies Azure-specific patterns including:
- Azure Functions runtime headers in GraphQL responses
- Azure App Service-specific error messages that reveal server details
- Azure API Management gateway configurations that may proxy introspection requests
For manual verification in Azure environments, you can use curl or Postman to test introspection:
curl -X POST https://yourapi.azurewebsites.net/graphql \
-H "Content-Type: application/json" \
-d '{"query": "query IntrospectionQuery { __schema { types { name } } }"}'
Azure-specific detection also involves checking your Azure Monitor logs for unusual GraphQL query patterns, particularly large data retrieval requests that might indicate an attacker using the exposed schema to craft optimized queries for data exfiltration.
Azure-Specific Remediation
Remediating GraphQL introspection in Azure requires both configuration changes and Azure-native security controls. For Apollo Server in Azure Functions:
const { ApolloServer, gql } = require('apollo-server-azure-functions');
const typeDefs = gql`
type Query {
hello: String
}
`;
const resolvers = {
Query: {
hello: () => 'Hello world!'
}
};
const server = new ApolloServer({
typeDefs,
resolvers,
introspection: process.env.NODE_ENV === 'development',
playground: process.env.NODE_ENV === 'development'
});
module.exports = server.createHandler();
For Hot Chocolate in Azure App Service, disable introspection in production:
services.AddGraphQLServer()
.AddQueryType<Query>()
.ModifyOptions(opts => {
opts.EnableIntrospection = !IsProduction();
});
Azure-specific security controls include:
- Azure Web Application Firewall (WAF) rules to block introspection queries
- Azure API Management policies to filter GraphQL introspection requests
- Azure Front Door with custom rules to inspect GraphQL payloads
Implement Azure Active Directory authentication for your GraphQL endpoints to ensure only authorized users can access the API:
const server = new ApolloServer({
typeDefs,
resolvers,
plugins: [
ApolloServerPluginAzureApollo({
appId: process.env.AZURE_APP_ID,
appSecret: process.env.AZURE_APP_SECRET,
tenantId: process.env.AZURE_TENANT_ID
})
]
});
Additionally, use Azure Key Vault to store GraphQL schema definitions securely and rotate API keys regularly to minimize the impact of potential schema exposure.
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 |