Mongoose populate() $where injection (CVE-2025-23061, CVE-2024-53900) enables RCE on Node.js servers; F5 sees mass exploitation as unlikely
F5 Labs analyzes CVE-2025-23061 and its predecessor CVE-2024-53900, a CVSS 9.0 flaw in the Mongoose MongoDB client library that allows remote code execution on Node.js API servers. The bug abuses the populate method, which accepts a $where clause containing arbitrary JavaScript. The initial fix for CVE-2024-53900 blocked only top-level $where, and CVE-2025-23061 showed that nested $where clauses are equally exploitable. F5 argues that mass exploitation is unlikely because MongoDB is not a common choice for enterprise internet-facing devices, so this is not comparable to the TP-Link or MoveIt waves. The most exposed are SaaS startups that built on MongoDB around 2015. The article does not report any in-the-wild exploitation.
Technical Details
- Exploitation uses
populatewith a malicious$whereexpression. Atypeof global != 'undefined' ? ... : 1check determines whether the code runs on the Node.js client or the MongoDB server, because server-side execution is far less risky. - The PoC reaches
global.process.mainModule.constructor, loadschild_processand runs system commands (the classiccalc.exedemonstration). A real payload could be a Node.js reverse shell, more likely built onnet.Socketto avoid system calls that would alert EDR. - Vulnerable mongoose versions:
<6.13.6,>=7.0.0 <7.8.4, and>=8.0.0 <8.9.5. - Node.js lacks runtime type checking and most API frameworks do not push input validation, which makes this class of injection common.
- A WAF rule or middleware that blocks
$-prefixed request elements is described as roughly 99% of a mitigation, but it must recurse through the whole request. It is harder to apply when a parameter such asrefine_byis passed straight into$where.
Remediation
- Search the code base for
populateand coerce its input, e.g.populate(untrusted_input.toString()). Also consider transitive dependencies. - Check
package-lock/yarn.lock(notpackage.json) for mongoose and upgrade to a fixed version (6.13.6, 7.8.4, 8.9.5 or later). The upgrade is non-breaking if dependencies are otherwise current. - Deploy a WAF rule or Node.js middleware that recursively blocks
$-prefixed keys such as$where. - Add schema validation (e.g. joi, AVR, json-schema). For new projects, consider Fastify, which makes input validation easy, and enforce schema use on all endpoints with a custom SAST rule.
Linha do tempo
-
Mongoose populate() $where injection (CVE-2025-23061, CVE-2024-53900) enables RCE on Node.js servers; F5 sees mass exploitation as unlikely
ler a análise desta fonte ocultar
F5 Labs analyzes CVE-2025-23061 and its predecessor CVE-2024-53900, a CVSS 9.0 flaw in the Mongoose MongoDB client library that allows remote code execution on Node.js API servers. The bug abuses the
populatemethod, which accepts a$whereclause containing arbitrary JavaScript. The initial fix for CVE-2024-53900 blocked only top-level$where, and CVE-2025-23061 showed that nested$whereclauses are equally exploitable. F5 argues that mass exploitation is unlikely because MongoDB is not a common choice for enterprise internet-facing devices, so this is not comparable to the TP-Link or MoveIt waves. The most exposed are SaaS startups that built on MongoDB around 2015. The article does not report any in-the-wild exploitation.Technical Details
- Exploitation uses
populatewith a malicious$whereexpression. Atypeof global != 'undefined' ? ... : 1check determines whether the code runs on the Node.js client or the MongoDB server, because server-side execution is far less risky. - The PoC reaches
global.process.mainModule.constructor, loadschild_processand runs system commands (the classiccalc.exedemonstration). A real payload could be a Node.js reverse shell, more likely built onnet.Socketto avoid system calls that would alert EDR. - Vulnerable mongoose versions:
<6.13.6,>=7.0.0 <7.8.4, and>=8.0.0 <8.9.5. - Node.js lacks runtime type checking and most API frameworks do not push input validation, which makes this class of injection common.
- A WAF rule or middleware that blocks
$-prefixed request elements is described as roughly 99% of a mitigation, but it must recurse through the whole request. It is harder to apply when a parameter such asrefine_byis passed straight into$where.
Remediation
- Search the code base for
populateand coerce its input, e.g.populate(untrusted_input.toString()). Also consider transitive dependencies. - Check
package-lock/yarn.lock(notpackage.json) for mongoose and upgrade to a fixed version (6.13.6, 7.8.4, 8.9.5 or later). The upgrade is non-breaking if dependencies are otherwise current. - Deploy a WAF rule or Node.js middleware that recursively blocks
$-prefixed keys such as$where. - Add schema validation (e.g. joi, AVR, json-schema). For new projects, consider Fastify, which makes input validation easy, and enforce schema use on all endpoints with a custom SAST rule.
- Exploitation uses