{"id":"CVE-2026-107353","state":"PUBLISHED","title":"traverse: set() can write to built-in prototypes via an untrusted path","description":"traverse (npm) versions 0.3.6 through 0.3.9, 0.4.0 through 0.4.6, 0.5.0 through 0.5.2, and 0.6.0 through 0.6.11 allow prototype pollution through set(). When the path passed to set() crosses a primitive value, the next path segment is resolved on that primitive's built-in prototype, so an application that passes an untrusted path to set() lets an attacker add or overwrite properties of String.prototype, Number.prototype, or Boolean.prototype using plain JSON data, for example traverse({ name: 'bob' }).set(['name', '__proto__', 'polluted'], 'yes'). Object.prototype was reachable only with a non-data path segment, such as an object whose toString returns a different value on each call, or through a Proxy that accepts an assignment without storing it. This is fixed in 0.3.10, 0.4.7, 0.5.3, and 0.6.12.","publishedAt":"2026-10-07T19:35:15.351Z","updatedAt":"2026-10-07T20:37:09.233Z","severity":{"score":6.9,"label":"Medium","version":"4.0","vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:L/VA:L/SC:N/SI:N/SA:N","source":"harborist"},"assigner":"harborist","products":["ljharb traverse"],"affected":[{"vendor":"ljharb","product":"traverse","packageName":"traverse","defaultStatus":"unaffected","versions":[{"version":"0.3.6","status":"affected","lessThan":"0.3.10","versionType":"semver"},{"version":"0.4.0","status":"affected","lessThan":"0.4.7","versionType":"semver"},{"version":"0.5.0","status":"affected","lessThan":"0.5.3","versionType":"semver"},{"version":"0.6.0","status":"affected","lessThan":"0.6.12","versionType":"semver"}],"collectionURL":"https://www.npmjs.com","repo":"https://github.com/ljharb/js-traverse","programRoutines":[{"name":"set"}]}],"references":["https://github.com/ljharb/js-traverse/security/advisories/GHSA-rj28-8w7x-jmqc","https://github.com/ljharb/js-traverse/commit/81ccab43e379cf42eb2a5f689630f7f79b3d71b8","https://github.com/ljharb/js-traverse/commit/37a9ebd103d2a259c824c29cdcc3f0dfe1acffce"],"weaknesses":["CWE-1321"],"ingestedAt":"2026-10-29T20:10:23.711Z","source":{"repository":"CVEProject/cvelistV5","path":"cves/2026/107xxx/CVE-2026-107353.json","commit":"556c9d3a8cd17e218bb8e452ba7cd619a384ff47"},"raw":{"dataType":"CVE_RECORD","dataVersion":"5.2","cveMetadata":{"cveId":"CVE-2026-107353","state":"PUBLISHED","datePublished":"2026-10-07T19:35:15.351Z","dateUpdated":"2026-10-07T20:37:09.233Z","assignerShortName":"harborist","assignerOrgId":"7ffcee3d-2c14-4c3e-b844-86c6a321a158","dateReserved":"2026-10-07T19:20:21.848Z"},"containers":{"cna":{"title":"traverse: set() can write to built-in prototypes via an untrusted path","descriptions":[{"lang":"en","value":"traverse (npm) versions 0.3.6 through 0.3.9, 0.4.0 through 0.4.6, 0.5.0 through 0.5.2, and 0.6.0 through 0.6.11 allow prototype pollution through set(). When the path passed to set() crosses a primitive value, the next path segment is resolved on that primitive's built-in prototype, so an application that passes an untrusted path to set() lets an attacker add or overwrite properties of String.prototype, Number.prototype, or Boolean.prototype using plain JSON data, for example traverse({ name: 'bob' }).set(['name', '__proto__', 'polluted'], 'yes'). Object.prototype was reachable only with a non-data path segment, such as an object whose toString returns a different value on each call, or through a Proxy that accepts an assignment without storing it. This is fixed in 0.3.10, 0.4.7, 0.5.3, and 0.6.12."}],"affected":[{"vendor":"ljharb","product":"traverse","packageName":"traverse","defaultStatus":"unaffected","versions":[{"version":"0.3.6","status":"affected","lessThan":"0.3.10","versionType":"semver"},{"version":"0.4.0","status":"affected","lessThan":"0.4.7","versionType":"semver"},{"version":"0.5.0","status":"affected","lessThan":"0.5.3","versionType":"semver"},{"version":"0.6.0","status":"affected","lessThan":"0.6.12","versionType":"semver"}],"collectionURL":"https://www.npmjs.com","repo":"https://github.com/ljharb/js-traverse","programRoutines":[{"name":"set"}]}],"references":[{"url":"https://github.com/ljharb/js-traverse/security/advisories/GHSA-rj28-8w7x-jmqc","tags":["vendor-advisory"]},{"url":"https://github.com/ljharb/js-traverse/commit/81ccab43e379cf42eb2a5f689630f7f79b3d71b8","tags":["patch"]},{"url":"https://github.com/ljharb/js-traverse/commit/37a9ebd103d2a259c824c29cdcc3f0dfe1acffce","tags":["patch"]}],"metrics":[{"format":"CVSS","scenarios":[{"lang":"en","value":"GENERAL"}],"cvssV4_0":{"attackVector":"NETWORK","attackComplexity":"LOW","attackRequirements":"NONE","privilegesRequired":"NONE","userInteraction":"NONE","vulnConfidentialityImpact":"NONE","subConfidentialityImpact":"NONE","vulnIntegrityImpact":"LOW","subIntegrityImpact":"NONE","vulnAvailabilityImpact":"LOW","subAvailabilityImpact":"NONE","exploitMaturity":"NOT_DEFINED","Safety":"NOT_DEFINED","Automatable":"NOT_DEFINED","Recovery":"NOT_DEFINED","valueDensity":"NOT_DEFINED","vulnerabilityResponseEffort":"NOT_DEFINED","providerUrgency":"NOT_DEFINED","version":"4.0","baseSeverity":"MEDIUM","baseScore":6.9,"vectorString":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:L/VA:L/SC:N/SI:N/SA:N"}},{"format":"CVSS","scenarios":[{"lang":"en","value":"GENERAL"}],"cvssV3_1":{"version":"3.1","attackVector":"NETWORK","attackComplexity":"LOW","privilegesRequired":"NONE","userInteraction":"NONE","scope":"UNCHANGED","confidentialityImpact":"NONE","integrityImpact":"LOW","availabilityImpact":"LOW","baseSeverity":"MEDIUM","baseScore":6.5,"vectorString":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:L"}}],"problemTypes":[{"descriptions":[{"cweId":"CWE-1321","lang":"en","description":"CWE-1321 Improperly Controlled Modification of Object Prototype Attributes ('Prototype Pollution')","type":"CWE"}]}],"providerMetadata":{"shortName":"harborist","orgId":"7ffcee3d-2c14-4c3e-b844-86c6a321a158","dateUpdated":"2026-10-07T19:35:15.351Z"},"workarounds":[{"lang":"en","value":"Do not pass untrusted paths to set(). If that is not possible, require every path segment to be a string other than __proto__, constructor, or prototype, and confirm that each intermediate value along the path is an object before calling set().","supportingMedia":[{"type":"text/html","base64":false,"value":"<p>Do not pass untrusted paths to set(). If that is not possible, require every path segment to be a string other than __proto__, constructor, or prototype, and confirm that each intermediate value along the path is an object before calling set().</p>"}]}],"solutions":[{"lang":"en","value":"Upgrade to traverse 0.6.12 or later, or, on older release lines, to 0.5.3, 0.4.7, or 0.3.10.","supportingMedia":[{"type":"text/html","base64":false,"value":"<p>Upgrade to traverse 0.6.12 or later, or, on older release lines, to 0.5.3, 0.4.7, or 0.3.10.</p>"}]}],"source":{"advisory":"GHSA-rj28-8w7x-jmqc","discovery":"INTERNAL"}},"adp":[{"title":"CISA ADP Vulnrichment","metrics":[{"other":{"type":"ssvc","content":{"timestamp":"2026-10-07T20:36:56.178663Z","id":"CVE-2026-107353","options":[{"Exploitation":"none"},{"Automatable":"yes"},{"Technical Impact":"partial"}],"role":"CISA Coordinator","version":"2.0.3"}}}],"providerMetadata":{"shortName":"CISA-ADP","orgId":"134c704f-9b21-4f2e-91b3-4a467353bcc0","dateUpdated":"2026-10-07T20:37:09.233Z"}}]}}}