VYPR
High severityOSV Advisory· Published Dec 16, 2025· Updated Apr 15, 2026

CVE-2025-68130

CVE-2025-68130

Description

tRPC allows users to build and consume fully typesafe APIs without schemas or code generation. Starting in version 10.27.0 and prior to versions 10.45.3 and 11.8.0, a A prototype pollution vulnerability exists in @trpc/server's formDataToObject function, which is used by the Next.js App Router adapter. An attacker can pollute Object.prototype by submitting specially crafted FormData field names, potentially leading to authorization bypass, denial of service, or other security impacts. Note that this vulnerability is only present when using experimental_caller / experimental_nextAppDirCaller. Versions 10.45.3 and 11.8.0 fix the issue.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
@trpc/servernpm
>= 10.27.0, < 10.45.310.45.3
@trpc/servernpm
>= 11.0.0, < 11.8.011.8.0

Affected products

1
  • Range: v10.27.0, v10.27.1, v10.27.2, …

Patches

1
78629d524968

Fix bug (#7043)

https://github.com/trpc/trpcNick LucasDec 13, 2025via ghsa
1 file changed · +18 3
  • packages/server/src/unstable-core-do-not-import/http/formDataToObject.ts+18 3 modified
    @@ -2,6 +2,10 @@
     
     const isNumberString = (str: string) => /^\d+$/.test(str);
     
    +// Prototype pollution guard
    +const isUnsafeKey = (key: string) =>
    +  key === '__proto__' || key === 'constructor' || key === 'prototype';
    +
     function set(
       obj: Record<string, any>,
       path: readonly string[],
    @@ -12,8 +16,13 @@ function set(
         const key = newPath.shift()!;
         const nextKey = newPath[0]!;
     
    -    if (!obj[key]) {
    -      obj[key] = isNumberString(nextKey) ? [] : {};
    +    // Skip unsafe keys to prevent prototype pollution
    +    if (isUnsafeKey(key)) {
    +      return;
    +    }
    +
    +    if (!Object.hasOwn(obj, key)) {
    +      obj[key] = isNumberString(nextKey) ? [] : Object.create(null);
         } else if (Array.isArray(obj[key]) && !isNumberString(nextKey)) {
           obj[key] = Object.fromEntries(Object.entries(obj[key]));
         }
    @@ -23,6 +32,12 @@ function set(
         return;
       }
       const p = path[0]!;
    +
    +  // Skip unsafe keys to prevent prototype pollution
    +  if (isUnsafeKey(p)) {
    +    return;
    +  }
    +
       if (obj[p] === undefined) {
         obj[p] = value;
       } else if (Array.isArray(obj[p])) {
    @@ -33,7 +48,7 @@ function set(
     }
     
     export function formDataToObject(formData: FormData) {
    -  const obj: Record<string, unknown> = {};
    +  const obj: Record<string, unknown> = Object.create(null);
     
       for (const [key, value] of formData.entries()) {
         const parts = key.split(/[\.\[\]]/).filter(Boolean);
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

4

News mentions

0

No linked articles in our index yet.