From 779413ece63e9f9c5d4c108918fa9990679beb6c Mon Sep 17 00:00:00 2001 From: spidershield-contrib Date: Sat, 14 Mar 2026 22:10:22 -0700 Subject: [PATCH] fix(graphql): prevent GraphQL injection in fetchTypeDetails The typeName parameter was interpolated directly into a GraphQL query string via template literal, allowing injection of arbitrary GraphQL syntax through crafted type names (e.g., a name containing `")`). Use a GraphQL variable ($typeName) instead of string interpolation so the value is properly handled by the GraphQL engine as data, not as part of the query structure. --- apps/graphql/src/tools/graphql.tools.ts | 30 +++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/apps/graphql/src/tools/graphql.tools.ts b/apps/graphql/src/tools/graphql.tools.ts index aea4f415..755bf22c 100644 --- a/apps/graphql/src/tools/graphql.tools.ts +++ b/apps/graphql/src/tools/graphql.tools.ts @@ -115,8 +115,8 @@ async function fetchSchemaOverview(apiToken: string): Promise { const typeDetailsQuery = ` - query TypeDetails { - __type(name: "${typeName}") { + query TypeDetails($typeName: String!) { + __type(name: $typeName) { name kind description @@ -174,8 +174,30 @@ async function fetchTypeDetails(typeName: string, apiToken: string): Promise(typeDetailsQuery, apiToken) - return response + const response = await fetch(CLOUDFLARE_GRAPHQL_ENDPOINT, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${apiToken}`, + }, + body: JSON.stringify({ + query: typeDetailsQuery, + variables: { typeName }, + }), + }) + + if (!response.ok) { + throw new Error(`Failed to execute GraphQL request: ${response.statusText}`) + } + + const data = graphQLResponseSchema.parse(await response.json()) + + if (data && data.errors && Array.isArray(data.errors) && data.errors.length > 0) { + const errorMessages = data.errors.map((e: { message: string }) => e.message).join(', ') + console.warn(`GraphQL errors: ${errorMessages}`) + } + + return data as unknown as TypeDetailsResponse } /**