Skip to content

Commit 1395336

Browse files
1 parent ac78bc7 commit 1395336

2 files changed

Lines changed: 72 additions & 1 deletion

File tree

advisories/github-reviewed/2026/01/GHSA-5qw5-wf2q-f538/GHSA-5qw5-wf2q-f538.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"schema_version": "1.4.0",
33
"id": "GHSA-5qw5-wf2q-f538",
4-
"modified": "2026-01-16T19:20:40Z",
4+
"modified": "2026-01-21T16:35:36Z",
55
"published": "2026-01-16T19:20:40Z",
66
"aliases": [],
77
"summary": "ActiveRecord-JDBC-Adapter (AR-JDBC) lib/arjdbc/jdbc/adapter.rb sql.gsub() Function SQL Injection",
@@ -46,6 +46,10 @@
4646
"type": "WEB",
4747
"url": "https://github.com/jruby/activerecord-jdbc-adapter/blob/master/lib/arjdbc/jdbc/adapter.rb"
4848
},
49+
{
50+
"type": "WEB",
51+
"url": "https://github.com/rubysec/ruby-advisory-db/blob/master/gems/activerecord-jdbc-adapter/GHSA-5qw5-wf2q-f538.yml"
52+
},
4953
{
5054
"type": "WEB",
5155
"url": "https://github.com/rubysec/ruby-advisory-db/blob/master/gems/activerecord-jdbc-adapter/OSVDB-114854.yml"
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
{
2+
"schema_version": "1.4.0",
3+
"id": "GHSA-h3hw-29fv-2x75",
4+
"modified": "2026-01-21T16:36:27Z",
5+
"published": "2026-01-21T16:36:27Z",
6+
"aliases": [],
7+
"summary": "@envelop/graphql-modules has a Race Condition vulnerability",
8+
"details": "### Summary\nContext race condition when using `useGraphQLModules` plugin\n\n### Details\n\nRelated to: https://github.com/graphql-hive/graphql-modules/security/advisories/GHSA-53wg-r69p-v3r7\n\nWhen 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() and graphql-modules are used in Yoga with `useGraphQLModules(application)`. This issue was fixed in `graphql-modules` in `2.4.1` and `3.1.1` but using `useGraphQLModules` will bypass the `async_hooks` fix that was implemented.\n\n### PoC\n\nCreate the following `package.json` and run `npm i`\n\n```json\n{\n \"name\": \"poc\",\n \"scripts\": {\n \"compile\": \"tsc\",\n \"start\": \"npm run compile && node ./dist/src/index.js\",\n \"test\": \"npm run compile && node ./dist/test/bleedtest.js\"\n },\n \"dependencies\": {\n \"@envelop/graphql-modules\": \"^9.0.0\",\n \"graphql-yoga\": \"^5.0.0\",\n \"graphql\": \"^16.10.0\",\n \"graphql-modules\": \"3.1.1\",\n \"reflect-metadata\": \"0.2.1\",\n \"axios\": \"^1.8.4\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^22.14.1\",\n \"typescript\": \"^5.8.3\"\n }\n}\n```\n\nDefine the app entrypoint: `src/index.ts`\n\n```ts\nimport { module } from \"./module.js\";\nimport { useGraphQLModules } from '@envelop/graphql-modules'\nimport { createApplication } from \"graphql-modules\";\nimport { createServer } from 'node:http'\nimport { randomUUID } from \"node:crypto\";\nimport { createYoga } from 'graphql-yoga';\n\nconst application = createApplication({\n modules: [module]\n})\n\nconst yoga = createYoga({\n schema: application.schema,\n plugins: [useGraphQLModules(application)],\n context() {\n return {\n requestId: randomUUID(),\n }\n }\n})\n\nconst server = createServer(yoga)\nserver.listen(4001, '127.0.0.1', undefined, () => {\n console.info(\n `[Server] Running on http://localhost:4001/graphql`\n )\n})\n```\n\nCreate the test module: `src/module.ts`\n\n```ts\nimport { createModule, gql } from \"graphql-modules\";\nimport Service from \"./service.js\";\n\nconst typeDefs = gql`\n type Book {\n id1: String\n id2: String\n }\n type Query {\n books: [Book]\n }\n`;\n\nexport const module = createModule({\n id: 'book-module',\n typeDefs: [typeDefs],\n providers: [Service],\n resolvers: {\n Query: {\n // return one empty book\n books: () => [{}],\n },\n Book: {\n // return the requestId from the context\n id1: async (_root, _args, { injector } ) => {\n return injector.get(Service).get();\n },\n // return the requestId from the context of the service 100 ms later\n id2: async (_root, _args, { injector } ) => {\n await new Promise(resolve => setTimeout(resolve, 100));\n return injector.get(Service).get()\n },\n }\n }\n})\n```\n\nAdd the Service that's to be injected `src/service.ts`\n\n```ts\nimport { ExecutionContext, Injectable } from 'graphql-modules';\nimport 'reflect-metadata';\n\n@Injectable()\nexport default class Service {\n @ExecutionContext()\n private context: ExecutionContext;\n\n get() {\n return this.context.requestId;\n }\n}\n```\n\nAdd the test case `test/bleedtest.js`\n\n```ts\nimport axios from 'axios';\n\nconst url = 'http://localhost:4001/graphql';\nconst query = `query { books { id1 id2 } }`;\n\nconst makeGraphQLRequest = async () => {\n const response = await axios.post(url, { query });\n\n const book = response.data.data.books[0]\n if (book.id1 !== book.id2) {\n throw new Error(`wrong response with ids ${(book.id1)} and ${(book.id2)}`)\n }\n}\n\nconst numberOfRequests = 2;\nawait Promise.all(Array.from(\n { length: numberOfRequests },\n makeGraphQLRequest,\n));\n```\n\nThen run the server with `npm run start` in one terminal and the testcase in another with `npm run test`.\nThe returned IDs should be identical as they are both read from the context within the same request.\nHowever, there is a mismatch:\n\n```\n❯ npm run test\n\n> poc@1.0.0 test\n> npm run compile && node ./dist/test/bleedtest.js\n\n\n> poc@1.0.0 compile\n> tsc\n\nfile://<redacted>/dist/test/bleedtest.js:8\n throw new Error(`wrong response with ids ${(book.id1)} and ${(book.id2)}`);\n ^\n\nError: wrong response with ids c2d83151-0922-4f25-a3e9-2f03acc1376a and e16c7335-0eaa-4386-b415-869ee4b05315\n at makeGraphQLRequest (file://<redacted>/dist/test/bleedtest.js:8:15)\n at process.processTicksAndRejections (node:internal/process/task_queues:95:5)\n at async Promise.all (index 0)\n at async file://<redacted>/dist/test/bleedtest.js:12:1\n```\n\n### Impact\nAny application that uses `useGraphQLModules` from `@envelop/graphql-modules` along with services that inject the context using @ExecutionContext() from a singleton provider are at risk. The more traffic an application has, the higher the chance for parallel requests, the higher the risk.",
9+
"severity": [
10+
{
11+
"type": "CVSS_V4",
12+
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N"
13+
}
14+
],
15+
"affected": [
16+
{
17+
"package": {
18+
"ecosystem": "npm",
19+
"name": "@envelop/graphql-modules"
20+
},
21+
"ranges": [
22+
{
23+
"type": "ECOSYSTEM",
24+
"events": [
25+
{
26+
"introduced": "0"
27+
},
28+
{
29+
"fixed": "9.1.0"
30+
}
31+
]
32+
}
33+
]
34+
}
35+
],
36+
"references": [
37+
{
38+
"type": "WEB",
39+
"url": "https://github.com/graphql-hive/envelop/security/advisories/GHSA-h3hw-29fv-2x75"
40+
},
41+
{
42+
"type": "WEB",
43+
"url": "https://github.com/graphql-hive/graphql-modules/security/advisories/GHSA-53wg-r69p-v3r7"
44+
},
45+
{
46+
"type": "WEB",
47+
"url": "https://github.com/graphql-hive/envelop/commit/ab49fa259a51d976c437e084114e070b99720ba9"
48+
},
49+
{
50+
"type": "PACKAGE",
51+
"url": "https://github.com/graphql-hive/envelop"
52+
},
53+
{
54+
"type": "WEB",
55+
"url": "https://github.com/graphql-hive/envelop/releases/tag/release-1768928934700"
56+
}
57+
],
58+
"database_specific": {
59+
"cwe_ids": [
60+
"CWE-362"
61+
],
62+
"severity": "HIGH",
63+
"github_reviewed": true,
64+
"github_reviewed_at": "2026-01-21T16:36:27Z",
65+
"nvd_published_at": null
66+
}
67+
}

0 commit comments

Comments
 (0)