$function and server-side JavaScript hardening
Parent: MongoDB Query Shape Optimization: Sort, Pagination, Operators and Sharded Targeting · Published reference · snapshot 2026-10-24 · skill mongodb-cohort-9cff09d95361
↓ Facts as markdownall context files
Source-anchored research for $function and server-side JavaScript hardening. Run status: COMPLETED.
These notes link each claim to its source. Some citations identify archived research reports that are no longer hosted on this site. A published reference means the content is available; it does not certify independent review or accuracy.Read the editorial policy and follow the sources before relying on a claim.
How it works
- Do not accept client-controlled JavaScript or raw query objects. Build application-owned filters with driver APIs, validate expected value types, and allowlist fields and operators. JavaScript interpolation can enable data extraction, while client-supplied objects can introduce operators even when the application uses query objects. (high confidence) [source]
- Percona's June 17, 2026 advisory describes CVE-2026-11933 in the older BSON-to-JavaScript-array conversion path: an authenticated user with read privileges and scripting enabled could trigger memory disclosure or a crash. Its upstream ticket concerns BSON wrapper ownership. This historical evidence does not establish that MongoDB 9.0's WASM engine has the same vulnerability. (medium confidence) (verified as of 2026-06-17) [source]
How-to and procedures
- Prefer native aggregation expressions inside $expr over $where when they express the same predicate. Replacing $where with $expr plus $function still executes JavaScript and still requires scripting to be enabled. (high confidence) [source]
- Prefer native aggregation expressions, including through $expr, over $where when they express the same logic. If custom JavaScript is necessary, MongoDB prefers $function over $where; moving JavaScript under $expr does not eliminate JavaScript execution. (high confidence) [source]
Problems, failure modes and limitations
- $function uses a body containing JavaScript, an args array, and lang: "js" to define a custom aggregation expression. MongoDB recommends it only when native pipeline operators cannot fulfill the application's needs, because JavaScript execution may reduce performance. (high confidence) [source]
- $where itself cannot use indexes, and a $where-only filter requires a collection scan. If it cannot be removed, include ordinary selective predicates: MongoDB evaluates non-$where conditions first, and those conditions may use indexes. (low confidence) [source]
- If the application does not require $where, $function, $accumulator, or mapReduce, disable server-side scripting on mongod and mongos using security.javascriptEnabled: false or --noscripting. Inventory application queries before disabling because dependent operations will fail. (high confidence) [source]
- MongoDB 8.0 deprecated $function, $accumulator, and $where and logged warnings when they ran; deprecation did not mean immediate removal. (high confidence) (verified as of 2024-10-23) [source]
- MongoDB 9.0 reverses the MongoDB 8.0 deprecation of $function, $accumulator, and $where. Do not carry an unqualified "deprecated since 8.0" recommendation into 9.0 guidance. (low confidence) (verified as of 2026-09-28) [source]
- Starting in MongoDB 9.0, ppc64le mongod and mongos binaries omit the JavaScript engine: $function, $accumulator, $where, and mapReduce fail there. A configuration switch cannot restore support; rewrite the operations or use an architecture with a JavaScript engine. (high confidence) (verified as of 2026-10-14) [source]
- MongoDB 8.0 deprecated $function, $accumulator, and $where and logs warnings when they execute. MongoDB 9.0 reverses that deprecation and re-enables these functions using a WASM-based engine; a blanket claim that they remain deprecated in every version after 8.0 is incorrect. (high confidence) (verified as of 2026-09-28) [source]
Comparisons and alternatives
- Starting in MongoDB 9.0, server-side local Date operations use UTC instead of the mongod host time zone. Review $function date logic before upgrading; use native date operators with an explicit timezone, or explicit UTC JavaScript methods when UTC is intended. (high confidence) (verified as of 2026-10-14) [source]
Facts and statements
- Disabling JavaScript does not eliminate NoSQL operator injection. Non-JavaScript operators such as $ne or $regex can still change filter semantics if the application accepts unvalidated query structures; field, type, and operator validation remains necessary. (high confidence) [source]
- MongoDB attributes stronger sandboxing and isolation in 9.0 to its WASM-based JavaScript engine. This is an engine-hardening claim, not evidence that accepting untrusted query operators or JavaScript bodies becomes safe; application input validation is still necessary. (high confidence) (verified as of 2026-10-14) [source]
- A 2024 community discussion reports workloads where custom JavaScript outperformed native aggregation rewrites, including IP transformations. Treat these as workload-specific reports, not a transferable benchmark or proof that JavaScript is universally faster. (low confidence) [source]
- $function requires server-side scripting, which MongoDB documents as enabled by default. Do not assume installation defaults have already disabled JavaScript; inspect the configuration of the deployed version. (low confidence) (verified as of 2026-10-14) [source]
Children
- No children recorded.