| Package Name | Ecosystem | Vulnerable Versions | First Patched Version |
|---|---|---|---|
| @trpc/server | npm | >= 10.27.0, < 10.45.3 | 10.45.3 |
| @trpc/server | npm | >= 11.0.0, < 11.8.0 | 11.8.0 |
The vulnerability is a classic prototype pollution issue in the @trpc/server package, occurring in the formDataToObject utility function. This function is used by the Next.js App Router integration (experimental_nextAppDirCaller). The root cause is the set helper function, which recursively builds a JavaScript object from key paths derived from FormData field names.
The set function failed to block dangerous keys like __proto__. When a malicious FormData payload, such as one containing the field __proto__[isAdmin], was submitted, the key would be split into the path ['__proto__', 'isAdmin']. The set function would then be called with this path. The original code would recursively call set(obj['__proto__'], ['isAdmin'], 'true'), which resolves to set(Object.prototype, ['isAdmin'], 'true'), thereby adding the isAdmin property to the global Object.prototype.
As a result, any object in the application that doesn't have its own isAdmin property would inherit it from the polluted prototype. This could lead to severe security issues, most notably authorization bypass, where a check like if (user.isAdmin) would unexpectedly evaluate to true for any user.
The patch addresses this vulnerability by introducing an isUnsafeKey function to explicitly block keys like __proto__, constructor, and prototype within the set function. Additionally, it changes the initial object creation in formDataToObject to use Object.create(null), creating an object without a prototype, which prevents pollution of Object.prototype. The property existence check was also changed to Object.hasOwn() to avoid traversing the prototype chain. The identified vulnerable functions, set and formDataToObject, are the core components where the unsafe processing of malicious input occurs.
setpackages/server/src/unstable-core-do-not-import/http/formDataToObject.ts
formDataToObjectpackages/server/src/unstable-core-do-not-import/http/formDataToObject.ts