HIGH graphql introspectionfeathersjshmac signatures

Graphql Introspection in Feathersjs with Hmac Signatures

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

GraphQL introspection is a built-in query capability that allows clients to discover the schema, types, and operations available on a GraphQL endpoint. When used unintentionally in production, it can expose data model details, relationships, and resolver behavior to attackers. In FeathersJS, a common Node.js framework for building GraphQL APIs, introspection is often enabled by default during development or inadvertently left accessible in production deployments. If an API also relies only on Hmac signatures for request authentication without additional safeguards, the combination can create a misleading sense of security and expose an unauthenticated attack surface.

Hmac Signatures are typically used to verify the integrity and origin of requests by validating a shared secret and payload. In FeathersJS, you might implement Hmac validation at the transport layer (e.g., before a service method is invoked) to ensure requests originate from trusted sources. However, GraphQL introspection queries are often executed before application-level authentication hooks run, especially if they are reachable via an unauthenticated HTTP route or a GraphQL gateway that does not enforce authorization for introspection. An attacker can send an introspection query to the endpoint, retrieve the full schema, and then craft parameter tampering or IDOR attempts using type names and field definitions revealed by the introspection response. Even when Hmac Signatures protect mutation operations, introspection can bypass those protections if the validation logic does not explicitly reject introspection queries or if the Hmac verification is applied after schema introspection resolves.

In practice, this vulnerability manifests when:

  • Introspection is enabled in production without access controls.
  • Hmac verification is implemented as a global hook but does not exclude introspection queries.
  • The API exposes GraphQL endpoints at a path that does not require prior authentication.

For example, a FeathersJS service might define a custom hook to validate Hmac signatures, but if the hook is attached as a global before hook and introspection is not filtered out, an attacker can still retrieve schema details before the Hmac check is enforced or bypass it using a malformed request that avoids signature validation. This enables reconnaissance for further attacks such as BOLA/IDOR or property authorization abuse.

Hmac Signatures-Specific Remediation in Feathersjs — concrete code fixes

To secure a FeathersJS GraphQL API that uses Hmac Signatures while preventing unsafe introspection exposure, you must combine schema-level controls with request validation logic. Below are concrete remediation steps with code examples.

1. Disable introspection in production

Ensure that GraphQL introspection is disabled in production environments unless explicitly required for debugging. If you use @feathersjs/graphql or a custom GraphQL server setup, configure the introspection option accordingly.

const { GraphQLServer } = require('graphql-yoga');
const app = new GraphQLServer({
  typeDefs: 'schema.graphql',
  resolvers: require('./resolvers'),
  options: {
    introspection: process.env.NODE_ENV !== 'production'
  }
});

2. Filter introspection in Hmac validation hooks

Implement a Hmac signature validation hook that explicitly skips introspection queries. In FeathersJS, you can inspect the GraphQL operation type and reject or bypass validation for introspection when appropriate, or require Hmac for all operations including introspection.

const crypto = require('crypto');

function verifyHmacSignature(secret) {
  return context => {
    const { headers } = context.params;
    const received = headers['x-hmac-signature'];
    const payload = JSON.stringify(context.arguments);
    const expected = crypto.createHmac('sha256', secret).update(payload).digest('hex');

    if (received !== expected) {
      throw new Error('Invalid Hmac signature');
    }
    return context;
  };
}

// Apply as a service hook, ensuring introspection queries are also validated
app.service('graphql').hooks({
  before: [
    verifyHmacSignature(process.env.HMAC_SECRET)
  ]
});

3. Use a custom GraphQL context to enforce authorization

Leverage the GraphQL context to pass validated request metadata and ensure introspection is only permitted for authorized contexts. You can reject introspection based on the presence of a valid Hmac context or role claims.

function createContext(req, res) {
  const authHeader = req.headers['x-hmac-signature'];
  const isValid = validateHmac(req.body, authHeader);
  if (!isValid) {
    throw new Error('Unauthorized');
  }
  return {
    user: {
      role: 'authenticated',
      canIntrospect: true
    }
  };
}

const server = new GraphQLServer({
  typeDefs,
  resolvers,
  context: createContext
});

4. Separate GraphQL endpoint for introspection if required

If introspection must be available for tooling, host it behind an authenticated route or require Hmac for introspection operations explicitly. Do not rely on network-level obscurity.

app.post('/graphql-introspection', authenticateHmac, (req, res) => {
  const { query } = req.body;
  if (query.trim().includes('__schema')) {
    const schema = buildSchemaFromServices();
    res.json({ data: schema });
  } else {
    res.status(400).send('Introspection only');
  }
});

5. Combine with input validation and rate limiting

Even when Hmac Signatures are enforced, pair them with input validation and rate limiting to reduce the impact of any residual exposure. This ensures that abuse of introspection or brute-force attempts is constrained.

const validator = require('feathers-hooks-common').validateSchema;
const rateLimit = require('feathers-ratelimit');

app.service('graphql').hooks({
  before: [
    rateLimit({ window: 60*1000, max: 100 }),
    validator({ query: { type: 'string', maxLength: 2048 } })
  ]
});

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 Hmac Signatures alone prevent GraphQL introspection abuse?
No. Hmac Signatures verify request integrity but do not restrict schema exposure. You must explicitly disable introspection or filter it in hooks to prevent unauthorized schema discovery.
Should introspection be completely disabled in all environments?
Disable introspection in production unless you have a controlled process for accessing schema data. Use environment-based configuration to enable it only in trusted debugging contexts.