HIGH graphql introspectionexpresshmac signatures

Graphql Introspection in Express with Hmac Signatures

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

GraphQL introspection is a feature that allows a client to query the structure of a GraphQL schema at runtime. In an Express server, enabling introspection on production endpoints can expose types, queries, and mutations that should remain internal. When Hmac Signatures are used for request authentication but are applied only to selected routes or inconsistently, an attacker can exploit the disparity to learn about the API surface without needing valid credentials.

Consider an Express setup where Hmac Signatures validate only specific admin routes, while the GraphQL endpoint remains open for introspection. An attacker can send an introspection query to the GraphQL endpoint and analyze the returned schema to discover other routes that require Hmac Signatures. By correlating endpoint paths and operation names revealed through introspection with the protected routes, the attacker can infer which operations might accept Hmac Signatures and potentially craft replay or tampering attacks.

GraphQL introspection responses include type definitions, input fields, and example values, which can inadvertently reveal business logic, data models, and authorization boundaries. If Hmac Signatures are generated using a predictable pattern or shared secret without additional context (such as timestamps or nonce), an attacker who observes a signed request can attempt to reproduce the signature for related operations discovered via introspection.

Moreover, misconfigured CORS settings combined with introspection can amplify the risk. An attacker can run browser-based introspection queries from a malicious page if CORS permits the GraphQL endpoint, and then use the schema details to plan further attacks against Hmac-protected routes. Even without modifying server-side code, the information leakage from introspection can guide social engineering or token replay attempts.

In practice, this combination becomes a two-phase process: first, gather schema and endpoint information through introspection; second, use that knowledge to target Hmac-signed operations with tampered payloads or signature reuse. Because GraphQL allows querying nested and relational fields, an attacker can probe for data exposure risks that align with privileged operations protected by Hmac Signatures.

Hmac Signatures-Specific Remediation in Express — concrete code fixes

To mitigate risks related to GraphQL introspection and Hmac Signatures in Express, apply consistent authentication, disable introspection in production, and ensure Hmac verification covers all relevant routes with secure practices.

1. Disable GraphQL introspection in production

Set introspection to false when initializing your GraphQL server. This prevents runtime schema discovery while preserving functionality in development.

const { ApolloServer } = require('apollo-server-express');
const typeDefs = require('./schema');
const resolvers = require('./resolvers');

const server = new ApolloServer({
  typeDefs,
  resolvers,
  introspection: process.env.NODE_ENV === 'development',
});

2. Apply Hmac Signatures uniformly to all sensitive routes

Use middleware to validate Hmac Signatures for both GraphQL and REST endpoints. This removes the route-level disparity that attackers exploit.

const crypto = require('crypto');
const express = require('express');
const app = express();

const SHARED_SECRET = process.env.HMAC_SECRET;

function verifyHmac(req, res, next) {
  const signature = req.headers['x-hmac-signature'];
  const timestamp = req.headers['x-timestamp'];
  const nonce = req.headers['x-nonce'];

  if (!signature || !timestamp || !nonce) {
    return res.status(401).json({ error: 'Missing Hmac headers' });
  }

  // Basic replay protection: reject if timestamp is older than 5 minutes
  const now = Math.floor(Date.now() / 1000);
  if (Math.abs(now - parseInt(timestamp, 10)) > 300) {
    return res.status(401).json({ error: 'Request expired' });
  }

  const payload = `${timestamp}:${nonce}:${req.method}:${req.path}`;
  const expected = crypto.createHmac('sha256', SHARED_SECRET)
                         .update(payload)
                         .digest('hex');

  if (!crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected))) {
    return res.status(403).json({ error: 'Invalid Hmac signature' });
  }
  return next();
}

app.use(verifyHmac);
app.use('/graphql', (req, res, next) => {
  // Ensure GraphQL endpoint also respects Hmac validation
  verifyHmac(req, res, next);
}, graphqlHTTP({
  schema: server.schema,
  graphiql: process.env.NODE_ENV === 'development',
}));

3. Include contextual data in Hmac payload

Avoid using only static path and method. Include a nonce and timestamp to prevent replay attacks and ensure each signature is unique.

const payload = `${timestamp}:${nonce}:${req.method}:${req.path}:${JSON.stringify(req.body)}`;

4. Enforce CORS and limit exposure

Restrict origins and avoid exposing GraphQL endpoints to untrusted domains. This reduces the chance that introspection results are harvested from browser contexts.

const cors = require('cors');
app.use(cors({
  origin: process.env.ALLOWED_ORIGINS ? process.env.ALLOWED_ORIGINS.split(',') : false,
  credentials: true,
}));

5. Combine with schema directives

Use schema-level directives to conditionally hide introspection fields or require elevated privileges for sensitive queries, complementing Hmac-based route protection.

# Example directive usage (schema definition)
directive @auth(role: String!) on OBJECT | FIELD_DEFINITION

6. Monitor and rotate secrets

Regularly rotate the Hmac secret and audit access patterns. If introspection must remain enabled in staging, ensure it is strictly limited to trusted networks.

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 with Hmac Signatures?
It is not recommended to enable introspection in production even with Hmac Signatures, as it exposes schema details that can aid attackers. If required for tooling, restrict introspection to specific roles and environments, and ensure Hmac covers all requests.
How often should the Hmac secret be rotated?
Rotate the Hmac secret regularly, for example monthly or after any suspected compromise, and always rotate after personnel changes. Combine rotation with nonce and timestamp checks to reduce replay risk.