CVE-2025-57353
Description
The Runtime components of messageformat package for Node.js before 3.0.2 contain a prototype pollution vulnerability. Due to insufficient validation of nested message keys during the processing of message data, an attacker can manipulate the prototype chain of JavaScript objects by providing specially crafted input. This can result in the injection of arbitrary properties into the Object.prototype, potentially leading to denial of service conditions or unexpected application behavior. The vulnerability allows attackers to alter the prototype of base objects, impacting all subsequent object instances throughout the application's lifecycle.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Prototype pollution vulnerability in messageformat Node.js package before 3.0.2 allows attackers to inject properties into Object.prototype via crafted message keys, leading to DoS or unexpected behavior.
Vulnerability
Details
The @messageformat/runtime package, part of the messageformat monorepo for Node.js, contains a prototype pollution vulnerability (CWE-1321) in its Messages class. The addMessages method fails to validate nested message keys, allowing an attacker to use keys such as __proto__ to inject properties into Object.prototype [1][4]. This occurs because the library directly assigns nested objects without ensuring that the keys do not traverse the prototype chain [3].
Exploitation
An attacker can exploit this by providing specially crafted message data to an application that uses the vulnerable runtime components. The input can include nested key paths that reference __proto__, causing the library to set properties on the global object prototype [1][4]. No special privileges are required; any application that processes user-supplied messages (e.g., localization files or dynamic message definitions) is at risk.
Impact
Successful prototype pollution can lead to denial of service by corrupting object prototypes, causing unexpected application behavior or crashes. Additionally, it can broaden the attack surface for other prototype pollution exploits, as all objects in the application inherit the polluted properties [1][4].
Mitigation
The vulnerability is fixed in version 3.0.2 of the @messageformat/runtime package [3]. Users should update to this version or later. The fix introduces a _withNullPrototype helper that ensures nested objects are created with a null prototype, preventing prototype chain manipulation [3]. The messageformat project is available on GitHub [2].
AI Insight generated on May 19, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
@messageformat/runtimenpm | >= 3.0.1, < 3.0.2 | 3.0.2 |
Affected products
1- Range: 0.2.0, 0.2.1, 0.3.0-0, …
Patches
23e5b24afdddachore: Publish
4 files changed · +24 −5
mf1/packages/core/package.json+1 −1 modified@@ -33,7 +33,7 @@ "@messageformat/date-skeleton": "2.0.0-0", "@messageformat/number-skeleton": "2.0.0-0", "@messageformat/parser": "^5.1.0", - "@messageformat/runtime": "^3.0.1", + "@messageformat/runtime": "^3.0.2", "make-plural": "^7.0.0", "safe-identifier": "^0.4.1" },
mf1/packages/runtime/CHANGELOG.md+6 −0 modified@@ -3,6 +3,12 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [3.0.2](https://github.com/messageformat/messageformat/compare/@messageformat/runtime@3.0.1...@messageformat/runtime@3.0.2) (2025-10-30) + +### Bug Fixes + +* **runtime:** Avoid prototype pollution in `Messages.p.addMessages()` ([#464](https://github.com/messageformat/messageformat/issues/464)) + ## [3.0.1](https://github.com/messageformat/messageformat/compare/@messageformat/runtime@3.0.0...@messageformat/runtime@3.0.1) (2022-02-06) ### Bug Fixes
mf1/packages/runtime/package.json+1 −1 modified@@ -1,6 +1,6 @@ { "name": "@messageformat/runtime", - "version": "3.0.1", + "version": "3.0.2", "description": "Runtime components of messageformat", "keywords": [ "i18n",
package-lock.json+16 −3 modified@@ -138,7 +138,7 @@ "@messageformat/date-skeleton": "2.0.0-0", "@messageformat/number-skeleton": "2.0.0-0", "@messageformat/parser": "^5.1.0", - "@messageformat/runtime": "^3.0.1", + "@messageformat/runtime": "^3.0.2", "make-plural": "^7.0.0", "safe-identifier": "^0.4.1" } @@ -187,7 +187,7 @@ }, "mf1/packages/runtime": { "name": "@messageformat/runtime", - "version": "3.0.1", + "version": "3.0.2", "license": "MIT", "dependencies": { "make-plural": "^7.0.0" @@ -323,6 +323,7 @@ "integrity": "sha512-UlLAnTPrFdNGoFtbSXwcGFQBtQZJCNjaN6hQNP3UPvuNXT1i82N26KL3dZeIpNalWywr9IuQuncaAfUaS1g6sQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.27.1", @@ -4313,6 +4314,7 @@ "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@babel/parser": "^7.20.7", "@babel/types": "^7.20.7", @@ -4443,6 +4445,7 @@ "integrity": "sha512-iAFpG6DokED3roLSP0K+ybeDdIX6Bc0Vd3mLW5uDqThPWtNos3E+EqOM11mPQHKzfWHqEBuLjIlsBQQ8CsISmQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "undici-types": "~6.21.0" } @@ -4559,6 +4562,7 @@ "integrity": "sha512-g3WpVQHngx0aLXn6kfIYCZxM6rRJlWzEkVpqEFLT3SgEDsp9cpCbxxgwnE504q4H+ruSDh/VGS6nqZIDynP+vg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.39.0", "@typescript-eslint/types": "8.39.0", @@ -5090,6 +5094,7 @@ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -5629,6 +5634,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "caniuse-lite": "^1.0.30001726", "electron-to-chromium": "^1.5.173", @@ -6317,6 +6323,7 @@ "integrity": "sha512-TS9bTNIryDzStCpJN93aC5VRSW3uTx9sClUn4B87pwiCaJh220otoI0X8mJKr+VcPtniMdN8GKjlwgWGUv5ZKA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.12.1", @@ -8019,6 +8026,7 @@ "integrity": "sha512-d+DjBQ1tIhdz91B79mywH5yYu76bZuE96sSbxj8MkjWVx5WNdt1deEFRONVL4UkKLSrAbMkdhb24XN691yDRHg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "chalk": "^4.1.2", "graceful-fs": "^4.2.11", @@ -9373,6 +9381,7 @@ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, @@ -9599,6 +9608,7 @@ "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", "license": "MIT", + "peer": true, "dependencies": { "loose-envify": "^1.1.0" }, @@ -9889,6 +9899,7 @@ "integrity": "sha512-WMmLFI+Boh6xbop+OAGo9cQ3OgX9MIg7xOQjn+pTCwOkk+FNDAeAemXkJ3HzDJrVXleLOFVa1ipuc1AmEx1Dwg==", "devOptional": true, "license": "MIT", + "peer": true, "dependencies": { "@types/estree": "1.0.8" }, @@ -10603,7 +10614,8 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "dev": true, - "license": "0BSD" + "license": "0BSD", + "peer": true }, "node_modules/type-check": { "version": "0.4.0", @@ -10697,6 +10709,7 @@ "integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==", "dev": true, "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver"
82cd10b40e3ffix(mf1): Avoid prototype pollution in @messageformat/runtime/messages (#464)
2 files changed · +22 −8
mf1/packages/runtime/src/messages.test.ts+8 −0 modified@@ -139,3 +139,11 @@ it('addMessages', async () => { messages.addMessages(() => 'z', null, ['x', 'y']); expect(messages.get(['x', 'y'])).toBe('z'); }); + +it('prototype pollution', () => { + messages.addMessages({ payload: 'polluted' }, 'en', [ + '__proto__', + 'injectedProp' + ]); + expect(({} as any).injectedProp).toBeUndefined(); +});
mf1/packages/runtime/src/messages.ts+14 −8 modified@@ -110,7 +110,7 @@ export default class Messages { constructor(msgData: { [key: string]: MessageData }, defaultLocale?: string) { Object.keys(msgData).forEach(lc => { if (lc !== 'toString') { - this._data[lc] = msgData[lc]; + this._data[lc] = _withNullPrototype(msgData[lc]); if (defaultLocale === undefined) defaultLocale = lc; } }); @@ -171,17 +171,12 @@ export default class Messages { keypath?: string[] ) { const lc = locale || String(this.locale); - if (typeof data !== 'function') { - data = Object.keys(data).reduce<MessageData>((map, key) => { - if (key !== 'toString') map[key] = (data as MessageData)[key]; - return map; - }, {}); - } + data = _withNullPrototype(data); if (Array.isArray(keypath) && keypath.length > 0) { let parent = this._data[lc] as MessageData; for (let i = 0; i < keypath.length - 1; ++i) { const key = keypath[i]; - if (!parent[key]) parent[key] = {}; + if (!parent[key]) parent[key] = Object.create(null); parent = parent[key] as MessageData; } parent[keypath[keypath.length - 1]] = data; @@ -342,3 +337,14 @@ function _has( } return false; } + +function _withNullPrototype<T = MessageData | MessageFunction | string>( + value: T +): T { + if (!value || typeof value !== 'object') return value; + const data: MessageData = Object.create(null); + for (const [key, value_] of Object.entries(value)) { + data[key] = _withNullPrototype(value_); + } + return data as T; +}
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
7- github.com/advisories/GHSA-6xv4-9cqp-92rhghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2025-57353ghsaADVISORY
- github.com/VulnSageAgent/PoCs/tree/main/JavaScript/prototype-pollution/CVE-2025-57353nvdWEB
- github.com/messageformat/messageformat/commit/82cd10b40e3f922f990bbcf88a6d14b70c0a3ce0nvdWEB
- github.com/messageformat/messageformat/issues/453nvdWEB
- github.com/messageformat/messageformat/issues/453nvdWEB
- github.com/messageformat/messageformat/pull/464nvdWEB
News mentions
0No linked articles in our index yet.