fix(fetch): guard against Object.prototype[Symbol.iterator] pollution in header dispatch - #11177
fix(fetch): guard against Object.prototype[Symbol.iterator] pollution in header dispatch#11177bhumin18 wants to merge 13 commits into
Conversation
… in header dispatch
There was a problem hiding this comment.
All reported issues were addressed across 2 files
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
…dd regression tests
There was a problem hiding this comment.
All reported issues were addressed across 2 files (changes from recent commits).
Tip: Review your code locally with the cubic CLI to iterate faster.
Re-trigger cubic
…le explicit globalThis.fetch
…red env.fetch as custom
There was a problem hiding this comment.
All reported issues were addressed across 2 files (changes from recent commits).
Tip: Review your code locally with the cubic CLI to iterate faster.
Re-trigger cubic
… to test subprocess
…fe headers representation
There was a problem hiding this comment.
All reported issues were addressed across 2 files (changes from recent commits).
Tip: Review your code locally with the cubic CLI to iterate faster.
Re-trigger cubic
There was a problem hiding this comment.
All reported issues were addressed across 2 files (changes from recent commits).
Tip: Review your code locally with the cubic CLI to iterate faster.
Re-trigger cubic
|
Want your agent to iterate on Greptile's feedback? Try greploops. |
There was a problem hiding this comment.
All reported issues were addressed across 1 file (changes from recent commits).
Tip: Review your code locally with the cubic CLI to iterate faster.
Re-trigger cubic
There was a problem hiding this comment.
Native detection trusts source text
When an application installs a custom fetch wrapper before Axios is imported and its source contains [native code] or internal/deps/undici/undici, isNativeFunction classifies it as native. Axios then suppresses Object.prototype[Symbol.iterator] while invoking that wrapper synchronously. Wrapper code such as [...{}] consequently throws TypeError: {} is not iterable, rejecting an otherwise valid request. Native-function detection must not trust forgeable source-text markers.
Ran code and verified through T-Rex
Prompt To Fix With AI
This is a comment left during a code review.
Path: lib/adapters/fetch.js
Line: 40
Comment:
**Native detection trusts source text**
When an application installs a custom fetch wrapper before Axios is imported and its source contains `[native code]` or `internal/deps/undici/undici`, `isNativeFunction` classifies it as native. Axios then suppresses `Object.prototype[Symbol.iterator]` while invoking that wrapper synchronously. Wrapper code such as `[...{}]` consequently throws `TypeError: {} is not iterable`, rejecting an otherwise valid request. Native-function detection must not trust forgeable source-text markers.
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.
Summary
When
Object.prototype[Symbol.iterator]is polluted, Node.js/undici's internal header dispatch creates a plain{}for merged request headers and iterates it withfor...of. This causes the polluted iterator to inject or overwrite headers (such asAuthorization).Fix
In the fetch adapter, check for an own
Symbol.iteratorproperty onObject.prototyperight before creating theRequest/callingfetch(), temporarily remove it, and restore its exact property descriptor in afinallyblock.Verification
should not use inherited Symbol.iterator for request headersnpm run test:vitest:unit -- tests/unit/adapters/fetch.test.js: 69/69 passednpm run lint: Clean (0 errors)PRE_RELEASE_CHANGELOG.mdupdated as per guidelinesSummary by cubic
Description
Fixes a prototype pollution vulnerability in the fetch adapter where a polluted
Object.prototype[Symbol.iterator]could inject or override request headers such asAuthorizationduring Node.js/undici's header dispatch.Symbol.iteratoronObject.prototypeand temporarily removes it during synchronousRequestconstruction and fetch dispatch, skipping the guard when the descriptor is non-configurable.Headersinstance or entries array so theRequestconstructor never readsObject.prototype[Symbol.iterator]even when the polluted descriptor cannot be removed.finallyblock, so in-flight, never-settling, or rejected requests never observe an altered prototype.env.fetchorRequestimplementations; the nativefetchis captured once at module load and matched by identity, so a replacedglobalThis.fetchis treated as custom while an explicit nativeglobalThis.fetchis guarded.Docs
No documentation update needed; this is an internal security hardening fix.
Testing
Adds regression tests covering concurrent requests, never-settling fetches, rejections, custom
env.fetchandRequest, wrapped and replacedglobalThis.fetch, non-configurable descriptors, and explicitglobalThis.fetch. All unit tests pass with lint clean.Semantic version impact
Patch version change.
Written for commit 2885b48. Summary will update on new commits.