From 606b36da73f32a94e1ad2f4b45d3865a82268c3b Mon Sep 17 00:00:00 2001 From: tomaioo Date: Fri, 22 May 2026 11:12:08 -0700 Subject: [PATCH] fix(security): server-side request forgery (ssrf) in graphql hand The `data-driven-dependencies/pages/api/graphql.js` handler reads the `source` field from user-provided request body and passes it directly to the `graphql` function without validation. While it uses a queryMap for `id`-based lookups, when `requestParams.id` is not provided, it falls back to `requestParams.query` which allows arbitrary GraphQL query execution. More critically, the `queryMap` lookup uses unsanitized user input as a key, and the file path construction in `getConfig().serverRuntimeConfig.projectRoot` combined with `path.resolve` could potentially be exploited if `projectRoot` is manipulated. The main concern is that this endpoint appears to be an internal API but doesn't validate the origin, allowing potential SSRF if the GraphQL schema has introspection enabled or if there are internal-only mutations. Signed-off-by: tomaioo <203048277+tomaioo@users.noreply.github.com> --- data-driven-dependencies/pages/api/graphql.js | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/data-driven-dependencies/pages/api/graphql.js b/data-driven-dependencies/pages/api/graphql.js index c102f7e0..d7dfbff0 100644 --- a/data-driven-dependencies/pages/api/graphql.js +++ b/data-driven-dependencies/pages/api/graphql.js @@ -27,12 +27,21 @@ export default async function handler(req, res) { } const requestParams = JSON.parse(Buffer.concat(buffers).toString()); dataDrivenDependencies.reset(); + let source; + if (requestParams.id != null) { + if (typeof requestParams.id !== 'string' || !queryMap.hasOwnProperty(requestParams.id)) { + res.end(JSON.stringify({errors: [{message: 'Invalid query ID'}]})); + return; + } + source = queryMap[requestParams.id]; + } else { + res.end(JSON.stringify({errors: [{message: 'Query ID is required'}]})); + return; + } response = await graphql({ schema, rootValue, - source: requestParams.id - ? queryMap[requestParams.id] - : requestParams.query, + source, variableValues: requestParams.variables, }); }