| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
When Object.freeze(globalThis) is called before any undici-backed global
(fetch, WebSocket, Response, etc.) is accessed, the lazy initialisation
in setGlobalDispatcher throws:
TypeError: Cannot define property Symbol(undici.globalDispatcher.2),
object is not extensible
This is a regression introduced when globals were made lazy-loaded
(nodejs#45659). The Node.js security best practices guide explicitly
recommends Object.freeze(globalThis) as a monkey-patching defence
(CWE-349), so this failure is particularly unfortunate.
Fix: wrap the Object.defineProperty calls in setGlobalDispatcher with a
try/catch. When globalThis is not extensible the dispatcher is stored in
a module-level fallback variable. getGlobalDispatcher is updated to
return globalThis[symbol] ?? fallbackDispatcher so that the normal path
(extensible globalThis) is unchanged.
The bundled deps/undici/undici.js is updated to match.
A test is added in test/parallel/test-undici-frozen-globalthis.js that
freezes globalThis before accessing any of the affected globals.
Fixes: nodejs#46788
|
Review requested:
|
Sorry, something went wrong.
|
This change should go to - https://github.com/nodejs/undici, and once it has a new version with your changes merged, it will be included here. |
Sorry, something went wrong.
|
Thanks for the feedback! You're absolutely right, the fix should go upstream first. I'll close this PR and create a PR in the undici repository with the same fix. Once it's merged and a new version is released, it can be integrated into Node.js via the standard dependency update process. Closing in favour of upstream fix. |
Sorry, something went wrong.
| Back | FazBrowse Home | New Git URL |
Summary
When Object.freeze(globalThis) is called before any undici-backed global (fetch, WebSocket, Response, etc.) is accessed for the first time, the lazy initialisation inside setGlobalDispatcher throws:
TypeError: Cannot define property Symbol(undici.globalDispatcher.2), object is not extensibleThis is particularly problematic because the Node.js security best practices guide explicitly recommends Object.freeze(globalThis) as a defence against monkey-patching (CWE-349).
Root cause
setGlobalDispatcher unconditionally calls Object.defineProperty(globalThis, ...). When globalThis is not extensible the call throws instead of degrading gracefully.
This became observable after globals were made lazy-loaded in #45659.
Fix
Wrap the Object.defineProperty calls in setGlobalDispatcher with a try/catch. When globalThis is not extensible the dispatcher is stored in a module-level fallback variable. getGlobalDispatcher is updated to return globalThis[symbol] ?? fallbackDispatcher so the normal (extensible) path is unchanged.
deps/undici/undici.js (the bundled file) is updated to match the source change in deps/undici/src/lib/global.js.
Test
A new test test/parallel/test-undici-frozen-globalthis.js is added that:
Checklist
Fixes #46788