make fetch compatible with Object.freeze(globalThis)
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 7.7k
- Forks
- 880
- Avg merge
- 2d 16h
- Merged PRs (30d)
- 68
Description
This would solve...
The NodeJS "security best practices" document suggests using Object.freeze(globalThis) to ensure no globals can be replaced, but this is unexpectedly not compatible with the built-in fetch:
# node
Welcome to Node.js v23.5.0.
Type ".help" for more information.
> Object.freeze(globalThis);
[...]
> fetch('https://example.com');
Uncaught:
TypeError: Cannot define property Symbol(undici.globalDispatcher.1), object is not extensible
at Function.defineProperty (<anonymous>)
at setGlobalDispatcher2 (node:internal/deps/undici/undici:8241:14)
at lib/global.js (node:internal/deps/undici/undici:8235:7)
at __require (node:internal/deps/undici/undici:6:50)
at node:internal/deps/undici/undici:13478:52
at BuiltinModule.compileForInternalLoader (node:internal/bootstrap/realm:402:7)
at requireBuiltin (node:internal/bootstrap/realm:433:14)
at fetch (node:internal/bootstrap/web/exposed-window-or-worker:78:28)
The implementation should look like...
The issue is that undici attempts to add a dispatcher to globalThis: https://github.com/nodejs/undici/blob/bd98a6303e45d5e0d44192a93731b1defdb415f3/lib/global.js#L17 (there also seems to be another one for globalOrigin)
This makes sense when undici is used as a userspace library since it avoids extra resource useage due to multiple versions coexisting, but makes less sense when it is part of NodeJS itself. The NodeJS integration should probably side-step this, or alternatively register the necessary globals before handing over to user code.
I have also considered...
This burden could be shifted to the user if there were some way to pre-initialise fetch; then the user could call this before freezing globalThis:
fetch.initialise();
Object.freeze(globalThis);
But this is an unexpected requirement and likely to catch developers out. Better for it to be automatic.
Another alternative would be to update the recommended security practices to suggest a method of freezing the existing properties of globalThis without preventing defining new properties, but I am not aware of a standard way to do this.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the failure with Object.freeze(globalThis) followed by fetch in Node.js. Read lib/global.js and lib/web/fetch/global.js, especially their global dispatcher and globalOrigin initialization, then inspect the Node.js integration described in the issue. Done means built-in fetch works after globalThis is frozen without requiring users to pre-initialize it.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, node.js
- Domain
- backend, networking
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100