Every CVE Search/ Get API key

CVE-2026-23735

Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition') in graphql-modules

8.7 HighFix available

GraphQL Modules is a toolset of libraries and guidelines dedicated to create reusable, maintainable, testable and extendable modules out of your GraphQL server. From 2.2.1 to before 2.4.1 and 3.1.1, when 2 or more parallel requests are made which trigger the same service, the context of the requests is mixed up in the service when the context is injected via @ExecutionContext(). ExecutionContext is often used to pass authentication tokens from incoming requests to services loading data from backend APIs. This vulnerability is fixed in 2.4.1 and 3.1.1.

Attack profile

How easy it is to exploit

Attack vector
Network
Complexity
Low
Privileges needed
None
User interaction
None

What an attacker can affect

Confidentiality
None
Integrity
High
Availability
None

Exploit likelihood

0.56%Up 0.4 points since Jan 17, 2026
90%50%10%1%

What each source reports

CVE List Score used 8.7

Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition') in graphql-modules

GraphQL Modules is a toolset of libraries and guidelines dedicated to create reusable, maintainable, testable and extendable modules out of your GraphQL server. From 2.2.1 to before 2.4.1 and 3.1.1, when 2 or more parallel requests are made which trigger the same service, the context of the requests is mixed up in the service when the context is injected via @ExecutionContext(). ExecutionContext is often used to pass authentication tokens from incoming requests to services loading data from backend APIs. This vulnerability is fixed in 2.4.1 and 3.1.1.

Record
CVE-2026-23735
CVSS 4.0
8.7 HighCVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N
Weakness
CWE-362
Updated
2026-11-02
EUVDEUVD-2026-2862 8.7

GraphQL Modules is a toolset of libraries and guidelines dedicated to create reusable, maintainable, testable and extendable modules out of your GraphQL server. From 2.2.1 to before 2.4.1 and 3.1.1, when 2 or more parallel requests are made which trigger the same service, the context of the requests is mixed up in the service when the context is injected via @ExecutionContext(). ExecutionContext is often used to pass authentication tokens from incoming requests to services loading data from backend APIs. This vulnerability is fixed in 2.4.1 and 3.1.1.

Record
EUVD-2026-2862
CVSS 4.0
8.7 HighCVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N
Updated
2026-11-02
GitHub AdvisoriesGHSA-53wg-r69p-v3r7 8.7

GraphQL Modules has a Race Condition issue

Summary

Originally reported as an issue #2613 but should be elevated to a security issue as the ExecutionContext is often used to pass authentication tokens from incoming requests to services loading data from backend APIs.

Details

When 2 or more parallel requests are made which trigger the same service, the context of the requests is mixed up in the service when the context is injected via @ExecutionContext()

PoC

In a new project/folder, create and install the following package.json:

{
  "name": "GHSA-53wg-r69p-v3r7",
  "scripts": {
    "test": "jest"
  },
  "dependencies": {
    "graphql-modules": "2.4.0"
  },
  "devDependencies": {
    "@babel/plugin-proposal-class-properties": "^7.18.6",
    "@babel/plugin-proposal-decorators": "^7.28.6",
    "babel-plugin-parameter-decorator": "^1.0.16",
    "jest": "^29.7.0",
    "reflect-metadata": "^0.2.2"
  }
}

with:

npm i

configure babel.config.json using:

{
  "plugins": [
    ["@babel/plugin-proposal-decorators", { "legacy": true }],
    "babel-plugin-parameter-decorator",
    "@babel/plugin-proposal-class-properties"
  ]
}

then write the following test GHSA-53wg-r69p-v3r7.spec.ts:

require("reflect-metadata");
const {
  createApplication,
  createModule,
  Injectable,
  Scope,
  ExecutionContext,
  gql,
  testkit,
} = require("graphql-modules");

test("accessing a singleton provider context during another asynchronous execution", async () => {
  @Injectable({ scope: Scope.Singleton })
  class IdentifierProvider {
    @ExecutionContext()
    context;

    getId() {
      return this.context.identifier;
    }
  }

  const { promise: gettingBefore, resolve: gotBefore } = createDeferred();

  const { promise: waitForGettingAfter, resolve: getAfter } = createDeferred();

  const mod = createModule({
    id: "mod",
    providers: [IdentifierProvider],
    typeDefs: gql`
      type Query {
        getAsyncIdentifiers: Identifiers!
      }

      type Identifiers {
        before: String!
        after: String!
      }
    `,
    resolvers: {
      Query: {
        async getAsyncIdentifiers(_0, _1, context) {
          const before = context.injector.get(IdentifierProvider).getId();
          gotBefore();
          await waitForGettingAfter;
          const after = context.injector.get(IdentifierProvider).getId();
          return { before, after };
        },
      },
    },
  });

  const app = createApplication({
    modules: [mod],
  });

  const document = gql`
    {
      getAsyncIdentifiers {
        before
        after
      }
    }
  `;

  const firstResult$ = testkit.execute(app, {
    contextValue: {
      identifier: "first",
    },
    document,
  });

  await gettingBefore;

  const secondResult$ = testkit.execute(app, {
    contextValue: {
      identifier: "second",
    },
    document,
  });

  getAfter();

  await expect(firstResult$).resolves.toEqual({
    data: {
      getAsyncIdentifiers: {
        before: "first",
        after: "first",
      },
    },
  });

  await expect(secondResult$).resolves.toEqual({
    data: {
      getAsyncIdentifiers: {
        before: "second",
        after: "second",
      },
    },
  });
});

function createDeferred() {
  let resolve, reject;
  const promise = new Promise((res, rej) => {
    resolve = res;
    reject = rej;
  });
  return {
    promise,
    resolve,
    reject,
  };
}

and execute using:

npm test

Your project tree should look like this:

GHSA-53wg-r69p-v3r7
    package.json
    package-lock.json
    babel.config.json
    GHSA-53wg-r69p-v3r7.spec.js

Expected vs. Actual Outcome

- Expected  - 1
+ Received  + 1

  Object {
    "data": Object {
      "getAsyncIdentifiers": Object {
-       "after": "first",
+       "after": "second",
        "before": "first",
      },
    },
  }

Impact

Any application that uses services that inject the context using @ExecutionContext() from a singleton provider are at risk.…

Record
GHSA-53wg-r69p-v3r7
CVSS 4.0
8.7 HighCVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N
Weakness
CWE-362
Updated
2026-11-02
NVD 8.7

GraphQL Modules is a toolset of libraries and guidelines dedicated to create reusable, maintainable, testable and extendable modules out of your GraphQL server. From 2.2.1 to before 2.4.1 and 3.1.1, when 2 or more parallel requests are made which trigger the same service, the context of the requests is mixed up in the service when the context is injected via @ExecutionContext(). ExecutionContext is often used to pass authentication tokens from incoming requests to services loading data from backend APIs. This vulnerability is fixed in 2.4.1 and 3.1.1.

Record
CVE-2026-23735
CVSS 4.0
8.7 HighCVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X
Weakness
CWE-362
Updated
2026-11-02
OSV 8.7

Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition') in graphql-modules

GraphQL Modules is a toolset of libraries and guidelines dedicated to create reusable, maintainable, testable and extendable modules out of your GraphQL server. From 2.2.1 to before 2.4.1 and 3.1.1, when 2 or more parallel requests are made which trigger the same service, the context of the requests is mixed up in the service when the context is injected via @ExecutionContext(). ExecutionContext is often used to pass authentication tokens from incoming requests to services loading data from backend APIs. This vulnerability is fixed in 2.4.1 and 3.1.1.

Record
CVE-2026-23735
CVSS 4.0
8.7 HighCVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N
Weakness
CWE-362
Updated
2026-11-02
OSVGHSA-53wg-r69p-v3r7 8.7

GraphQL Modules has a Race Condition issue

Summary

Originally reported as an issue #2613 but should be elevated to a security issue as the ExecutionContext is often used to pass authentication tokens from incoming requests to services loading data from backend APIs.

Details

When 2 or more parallel requests are made which trigger the same service, the context of the requests is mixed up in the service when the context is injected via @ExecutionContext()

PoC

In a new project/folder, create and install the following package.json:

{
  "name": "GHSA-53wg-r69p-v3r7",
  "scripts": {
    "test": "jest"
  },
  "dependencies": {
    "graphql-modules": "2.4.0"
  },
  "devDependencies": {
    "@babel/plugin-proposal-class-properties": "^7.18.6",
    "@babel/plugin-proposal-decorators": "^7.28.6",
    "babel-plugin-parameter-decorator": "^1.0.16",
    "jest": "^29.7.0",
    "reflect-metadata": "^0.2.2"
  }
}

with:

npm i

configure babel.config.json using:

{
  "plugins": [
    ["@babel/plugin-proposal-decorators", { "legacy": true }],
    "babel-plugin-parameter-decorator",
    "@babel/plugin-proposal-class-properties"
  ]
}

then write the following test GHSA-53wg-r69p-v3r7.spec.ts:

require("reflect-metadata");
const {
  createApplication,
  createModule,
  Injectable,
  Scope,
  ExecutionContext,
  gql,
  testkit,
} = require("graphql-modules");

test("accessing a singleton provider context during another asynchronous execution", async () => {
  @Injectable({ scope: Scope.Singleton })
  class IdentifierProvider {
    @ExecutionContext()
    context;

    getId() {
      return this.context.identifier;
    }
  }

  const { promise: gettingBefore, resolve: gotBefore } = createDeferred();

  const { promise: waitForGettingAfter, resolve: getAfter } = createDeferred();

  const mod = createModule({
    id: "mod",
    providers: [IdentifierProvider],
    typeDefs: gql`
      type Query {
        getAsyncIdentifiers: Identifiers!
      }

      type Identifiers {
        before: String!
        after: String!
      }
    `,
    resolvers: {
      Query: {
        async getAsyncIdentifiers(_0, _1, context) {
          const before = context.injector.get(IdentifierProvider).getId();
          gotBefore();
          await waitForGettingAfter;
          const after = context.injector.get(IdentifierProvider).getId();
          return { before, after };
        },
      },
    },
  });

  const app = createApplication({
    modules: [mod],
  });

  const document = gql`
    {
      getAsyncIdentifiers {
        before
        after
      }
    }
  `;

  const firstResult$ = testkit.execute(app, {
    contextValue: {
      identifier: "first",
    },
    document,
  });

  await gettingBefore;

  const secondResult$ = testkit.execute(app, {
    contextValue: {
      identifier: "second",
    },
    document,
  });

  getAfter();

  await expect(firstResult$).resolves.toEqual({
    data: {
      getAsyncIdentifiers: {
        before: "first",
        after: "first",
      },
    },
  });

  await expect(secondResult$).resolves.toEqual({
    data: {
      getAsyncIdentifiers: {
        before: "second",
        after: "second",
      },
    },
  });
});

function createDeferred() {
  let resolve, reject;
  const promise = new Promise((res, rej) => {
    resolve = res;
    reject = rej;
  });
  return {
    promise,
    resolve,
    reject,
  };
}

and execute using:

npm test

Your project tree should look like this:

GHSA-53wg-r69p-v3r7
    package.json
    package-lock.json
    babel.config.json
    GHSA-53wg-r69p-v3r7.spec.js

Expected vs. Actual Outcome

- Expected  - 1
+ Received  + 1

  Object {
    "data": Object {
      "getAsyncIdentifiers": Object {
-       "after": "first",
+       "after": "second",
        "before": "first",
      },
    },
  }

Impact

Any application that uses services that inject the context using @ExecutionContext() from a singleton provider are at risk.…

Record
GHSA-53wg-r69p-v3r7
CVSS 4.0
8.7 HighCVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N
Weakness
CWE-362
Updated
2026-11-02

Affected products

Affected packages

Affected packages
PackageAffectedFixed
graphql-modules
npm
2.2.1 up to 2.4.1
2.4.1
graphql-modules
npm
3.0.0 up to 3.1.1
3.1.1

History

History
RecordedChangedSources
first indexedCVE List, EUVD, GitHub Advisories, NVD, OSV

Dates are when Every CVE recorded each change. Upstream dates may differ.

In short

CVE-2026-23735 is a high vulnerability (CVSS 8.7) in Graphql-hive Graphql-modules, published January 16, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.56%, the 46th percentile. Fixed in graphql-modules 2.4.1.

References

This page doesn't list everything

Left out here: the rest of 2 source descriptions. The JSON record has them.

MoveEnter Open