
Cloud Vulnerability DB
A community-led vulnerabilities database
CVE-2026-40190 is a prototype pollution vulnerability in the LangSmith JavaScript/TypeScript SDK (langsmith on npm) caused by an incomplete __proto__ guard in an internally vendored lodash set() utility. The flaw affects all versions up to and including 0.5.17; version 0.5.18 contains the fix. The Python SDK (langsmith on PyPI) is not affected. It was initially reported on 2026-03-24, confirmed and patched by the vendor on 2026-04-09, and published to the GitHub Advisory Database and NVD on 2026-04-10. The CVSS v3.1 base score is 5.6 (Medium) (Github Advisory, Feedly).
The root cause (CWE-1321: Improperly Controlled Modification of Object Prototype Attributes) lies in js/src/utils/lodash/baseAssignValue.ts, where the guard only checks if (key === "__proto__") but does not block the constructor or prototype keys. When set() is called with a path such as "constructor.prototype.polluted", lodash's castPath() splits it into ["constructor", "prototype", "polluted"], and baseSet() traverses obj.constructor → Object → Object.prototype, ultimately calling baseAssignValue(Object.prototype, "polluted", value) — a key that bypasses the guard entirely. The attack surface is the createAnonymizer() API: extractStringNodes() builds dotted paths from object keys, and if an attacker controls those keys (e.g., { "constructor.prototype.isAdmin": "secret" }), the write-back via set() pollutes Object.prototype for the entire Node.js process. Notably, the deepClone() step (JSON.parse/stringify) does not prevent this because clone.wrapper.constructor still resolves to the global Object constructor (Github Advisory, Github Advisory).
Successful exploitation pollutes Object.prototype across the entire Node.js process, meaning every object created after the pollution inherits the attacker-injected properties. This can enable authentication bypass (e.g., if (user.isAdmin) evaluates to true for all objects), remote code execution via template engines such as Pug, EJS, Handlebars, or Nunjucks that pass polluted properties to eval()/Function() sinks, denial of service by overwriting fundamental methods like toString, valueOf, or hasOwnProperty, and data exfiltration by polluting serialization methods. The scope is process-wide, meaning all downstream code in the same Node.js runtime is affected (Github Advisory, Github Advisory).
A proof-of-concept is included in the public security advisory, demonstrating that passing a crafted object with a key like "constructor.prototype.isAdmin" to createAnonymizer() successfully pollutes Object.prototype. No evidence of in-the-wild exploitation or threat actor attribution has been reported. The vulnerability is not listed in the CISA KEV catalog. The EPSS score is approximately 0.018% (0.04% per Feedly), indicating a low near-term exploitation probability (Github Advisory, Feedly).
langsmith npm package version ≤ 0.5.17 and exposes the createAnonymizer() API to attacker-controlled input (e.g., user-supplied data passed through an anonymization pipeline)."constructor.prototype.<property>" and the value matches the anonymizer's configured regex pattern (e.g., contains the word "secret"):const maliciousInput = {
wrapper: {
"constructor.prototype.isAdmin": "this-is-secret-data"
}
};anonymizer(maliciousInput). The extractStringNodes() function builds the path "wrapper.constructor.prototype.isAdmin", and the regex match triggers a write-back via set().set() call traverses obj.constructor → Object → Object.prototype and assigns the (partially redacted) value to Object.prototype.isAdmin, polluting all objects in the process.Object.prototype.isAdmin now truthy, any subsequent if (user.isAdmin) check in the application returns true for any object, granting unauthorized access. Alternatively, if a template engine is in use, craft a payload targeting a property that reaches an eval() or Function() sink for RCE (Github Advisory, Github Advisory).toString, hasOwnProperty, valueOf).constructor.prototype, __proto__, or prototype in data submitted to the createAnonymizer() API; these can be identified in application request logs or data pipeline audit trails.Upgrade the langsmith npm package to version 0.5.18 or later, which replaces the path-based set() write-back with direct parent-reference writes (internal.parent[internal.key] = node.value), eliminating prototype traversal entirely. The fix also removes the vulnerable vendored lodash utilities (baseAssignValue.ts, baseSet.ts, etc.) from the codebase. As a temporary workaround if immediate patching is not possible, validate and sanitize all input keys passed to createAnonymizer() to reject any segments matching constructor, prototype, or __proto__ before processing. The Python SDK (langsmith on PyPI) is not affected and requires no action (Github Advisory, Fix PR).
The vulnerability was reported by security researcher OneThing4101 and confirmed by LangChain maintainer Jacob Lee (jacoblee93), who merged the fix on April 9, 2026. The advisory was published at a Moderate severity rating, reflecting the high attack complexity required (the attacker must control keys in data processed by the anonymizer). No significant broader media coverage or notable community controversy has been identified beyond standard vulnerability database aggregation (Github Advisory, Fix PR).
Source: This report was generated using AI
Free Vulnerability Assessment
Evaluate your cloud security practices across 9 security domains to benchmark your risk level and identify gaps in your defenses.
Get a personalized demo
"Best User Experience I have ever seen, provides full visibility to cloud workloads."
"Wiz provides a single pane of glass to see what is going on in our cloud environments."
"We know that if Wiz identifies something as critical, it actually is."