Skip to content

fix(graphql): prevent prototype pollution via GraphQL field name#7902

Open
zbrydon wants to merge 2 commits intoDataDog:masterfrom
zbrydon:prevent-prototype-pollution
Open

fix(graphql): prevent prototype pollution via GraphQL field name#7902
zbrydon wants to merge 2 commits intoDataDog:masterfrom
zbrydon:prevent-prototype-pollution

Conversation

@zbrydon
Copy link
Copy Markdown

@zbrydon zbrydon commented Apr 1, 2026

What does this PR do?

Fixes a prototype pollution bug in the GraphQL instrumentation where a crafted query using __proto__ as a field name could mutate Object.prototype via the fields object used to track resolver spans.

Additionally hardens pathToArray to only include path segments that are strings or numbers, preventing non-string/non-number keys (such as those arising from a pollution attempt) from being passed into the trace serialisation pipeline - which would cause a DecodeError in the msgpack agent.

Changes

  • fields: Object.create(null) - The execution context's fields map is now created with a null prototype, so assigning __proto__ as a key stores it as a plain data property rather than triggering prototype mutation.
  • pathToArray key guard - Path segments are now only included in the flattened path if they are a string or number, preventing unexpected key types from reaching span tags and the trace serialisation layer.
  • New test - Adds a test asserting that a query containing __proto__ as a field name does not crash the instrumentation and that the result data has a null prototype (confirming Object.create(null) is in effect).

Motivation

Fixing the error I encountered:

TypeError: Cannot set properties of undefined (setting 'error')
    at dd-trace/packages/datadog-instrumentations/src/graphql.js:217:23
    at dd-trace/packages/datadog-instrumentations/src/graphql.js:246:11
    at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
    at async Promise.all (index 0)
    at async execute (@apollo/server/src/requestPipeline.ts:576:31)
    at async processGraphQLRequest (@apollo/server/src/requestPipeline.ts:454:26)
    at async internalExecuteOperation (@apollo/server/src/ApolloServer.ts:1370:12)
    at async runHttpQuery (@apollo/server/src/runHttpQuery.ts:248:27)
    at async runPotentiallyBatchedHttpQuery (@apollo/server/src/httpBatching.ts:85:12)
    at async ApolloServer.executeHTTPGraphQLRequest (@apollo/server/src/ApolloServer.ts:1144:14)

Without this fix, a GraphQL query such as { __proto__: hello } could silently pollute Object.prototype during execution tracing, potentially affecting all objects in the process. Even with the Object.create(null) fix alone, the __proto__ key would still flow through to the msgpack serialiser and cause a DecodeError: The type of key must be string or number but object when the trace was submitted to the agent.

@zbrydon zbrydon requested a review from a team as a code owner April 1, 2026 06:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant