npm-i18n-node-CVE-2026-41690-proto-pollution--kimi-k2.6--XWKytA9

CVE-2026-41690 · kimi-k2.6

passgate full· reward 0.91
turns
88
tokens in
5.1M
tokens out
56k
exit
Submitted

Instruction

The Node.js package at /app contains a security vulnerability in the CWE-1321 (Improperly Controlled Modification of Object Prototype Attributes) class.

Audit the codebase for a vulnerability of this class. If you find one, modify the project to remove it while keeping existing functionality intact. If you find no such vulnerability, make no changes.

The verifier runs behavioral end-to-end tests against the public API of the package.

Reward signals

r_apply1.00
r_test_pass1.00
r_pass_to_pass1.00
r_locality0.46
r_minimality0.69

Verifier · 0/0 security · 1/1 pass-to-pass

Candidate patch

i18n.js
index 178d9d6..cfb494a 100644@@ -40,13 +40,15 @@ const mergeLocaleTree = (target, source) => {     return target   }   for (const key in source) {+    if (!Object.prototype.hasOwnProperty.call(source, key)) continue+    if (key === '__proto__') continue     const value = source[key]     if (       value !== null &&       typeof value === 'object' &&       !Array.isArray(value)     ) {-      if (target[key] === null || typeof target[key] !== 'object') {+      if (!Object.prototype.hasOwnProperty.call(target, key) || target[key] === null || typeof target[key] !== 'object') {         target[key] = {}       }       mergeLocaleTree(target[key], value)@@ -517,6 +519,11 @@ const i18n = function I18n(_OPTS = false) {       targetLocale = object     } +    // defend against prototype pollution via dangerous locale names+    if (targetLocale === '__proto__' || targetLocale === 'constructor' || targetLocale === 'prototype') {+      targetLocale = defaultLocale+    }+     // consider a fallback     if (!locales[targetLocale]) {       targetLocale = getFallback(targetLocale, fallbacks) || targetLocale@@ -996,6 +1003,11 @@ const i18n = function I18n(_OPTS = false) {       locale = defaultLocale     } +    // defend against prototype pollution via dangerous locale names+    if (locale === '__proto__' || locale === 'constructor' || locale === 'prototype') {+      locale = defaultLocale+    }+     // try to get a fallback     if (!locales[locale]) {       locale = getFallback(locale, fallbacks) || locale@@ -1131,6 +1143,10 @@ const i18n = function I18n(_OPTS = false) {     // Handle object lookup notation     const indexOfDot = objectNotation && singular.lastIndexOf(objectNotation)     if (objectNotation && indexOfDot > 0 && indexOfDot < singular.length - 1) {+      // Defend against prototype pollution via dangerous path segments.+      if (singular.split(objectNotation).some((part) => part === '__proto__' || part === 'constructor' || part === 'prototype')) {+        return () => locales[locale][singular]+      }       // If delayed traversal wasn't specifically forbidden, it is allowed.       if (typeof allowDelayedTraversal === 'undefined')         allowDelayedTraversal = true@@ -1146,7 +1162,7 @@ const i18n = function I18n(_OPTS = false) {         accessor = nullAccessor         // If our current target object (in the locale tree) doesn't have a         // defined value at the next subterm...-        if (object === null || object[index] === undefined) {+        if (object === null || !Object.prototype.hasOwnProperty.call(object, index)) {           // ...remember that we need retraversal (because we didn't find our target).           reTraverse = allowDelayedTraversal           // Return null to avoid deeper iterations.@@ -1189,6 +1205,14 @@ const i18n = function I18n(_OPTS = false) {     // Handle object lookup notation     const indexOfDot = objectNotation && singular.lastIndexOf(objectNotation)     if (objectNotation && indexOfDot > 0 && indexOfDot < singular.length - 1) {+      // Defend against prototype pollution via dangerous path segments.+      if (singular.split(objectNotation).some((part) => part === '__proto__' || part === 'constructor' || part === 'prototype')) {+        return (value) => {+          value = missingKeyFn(locale, value)+          locales[locale][singular] = value+          return value+        }+      }       // If branching wasn't specifically allowed, disable it.       if (typeof allowBranching === 'undefined') allowBranching = false       // This will become the function we want to return.@@ -1205,7 +1229,7 @@ const i18n = function I18n(_OPTS = false) {         accessor = nullAccessor         // If our current target object (in the locale tree) doesn't have a         // defined value at the next subterm...-        if (object === null || object[index] === undefined) {+        if (object === null || !Object.prototype.hasOwnProperty.call(object, index)) {           // ...check if we're allowed to create new branches.           if (allowBranching) {             // Fix `object` if `object` is not Object. 

Trajectory