Security
Headlines
HeadlinesLatestCVEs

Headline

GHSA-hmfr-rx46-4jx2: GraphQL Armor Max-Depth Plugin Bypass via Introspection Query Obfuscation

Summary

A query depth restriction using the max-depth property can be bypassed if ignoreIntrospection is enabled (which is the default configuration) by naming your query/fragment __schema.

Details

At the start of the countDepth function, we have the following check for the ignoreIntrospection option:

    if (this.config.ignoreIntrospection && 'name' in node && node.name?.value === '__schema') {
        return 0;
    }

However, the node can be one of: FieldNode, FragmentDefinitionNode, InlineFragmentNode, OperationDefinitionNode, FragmentSpreadNode.

For example, consider sending the following query:

query hello {
  books {
    title
  }
}

This would create an OperationDefinitionNode where node.name.value == 'hello'

The proper way to handle this is to check explicitly for the __schema field, which corresponds to a FieldNode.

The fix is

    if (
      this.config.ignoreIntrospection &&
      'name' in node &&
      node.name?.value === '__schema' &&
      node.kind === Kind.FIELD
    ) {
      return 0;
    }

This ensures that the node is explicitly a FieldNode.

PoC

Max depth: 6

query {
  books {
    author {
      books {
        author {
          ...__schema
        }
      }
    }
  }
}
fragment __schema on Author {
  books {
    title
  }
}

Impact

This issue affects applications using the GraphQL Armor Depth Limit plugin with ignoreIntrospection enabled.

Fix

This is fixed in PR#823

ghsa
#git#auth

Summary

A query depth restriction using the max-depth property can be bypassed if ignoreIntrospection is enabled (which is the default configuration) by naming your query/fragment __schema.

Details

At the start of the countDepth function, we have the following check for the ignoreIntrospection option:

if (this.config.ignoreIntrospection && 'name' in node && node.name?.value \=== '\_\_schema') {
    return 0;
}

However, the node can be one of: FieldNode, FragmentDefinitionNode, InlineFragmentNode, OperationDefinitionNode, FragmentSpreadNode.

For example, consider sending the following query:

query hello { books { title } }

This would create an OperationDefinitionNode where node.name.value == ‘hello’

The proper way to handle this is to check explicitly for the __schema field, which corresponds to a FieldNode.

The fix is

if (
  this.config.ignoreIntrospection &&
  'name' in node &&
  node.name?.value \=== '\_\_schema' &&
  node.kind \=== Kind.FIELD
) {
  return 0;
}

This ensures that the node is explicitly a FieldNode.

PoC

Max depth: 6

query { books { author { books { author { …__schema } } } } } fragment __schema on Author { books { title } }

Impact

This issue affects applications using the GraphQL Armor Depth Limit plugin with ignoreIntrospection enabled.

Fix

This is fixed in PR#823

References

  • GHSA-hmfr-rx46-4jx2
  • Escape-Technologies/graphql-armor#823
  • Escape-Technologies/graphql-armor@1f923bc

ghsa: Latest News

GHSA-224p-v68g-5g8f: GraphQL Armor Max-Depth Plugin Bypass via fragment caching