fix(fetch): guard against Object.prototype[Symbol.iterator] pollution in header dispatch by bhumin18 · Pull Request #11177 · axios/axios · GitHub
Skip to content

fix(fetch): guard against Object.prototype[Symbol.iterator] pollution in header dispatch - #11177

Open
bhumin18 wants to merge 13 commits into
axios:v1.xfrom
bhumin18:fix/fetch-proto-iterator-pollution
Open

fix(fetch): guard against Object.prototype[Symbol.iterator] pollution in header dispatch#11177
bhumin18 wants to merge 13 commits into
axios:v1.xfrom
bhumin18:fix/fetch-proto-iterator-pollution

Conversation

@bhumin18

@bhumin18 bhumin18 commented Aug 31, 2026

Copy link
Copy Markdown

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 with for...of. This causes the polluted iterator to inject or overwrite headers (such as Authorization).

Fix

In the fetch adapter, check for an own Symbol.iterator property on Object.prototype right before creating the Request/calling fetch(), temporarily remove it, and restore its exact property descriptor in a finally block.

Verification

  • Fixes the failing test: should not use inherited Symbol.iterator for request headers
  • npm run test:vitest:unit -- tests/unit/adapters/fetch.test.js: 69/69 passed
  • npm run lint: Clean (0 errors)
  • PRE_RELEASE_CHANGELOG.md updated as per guidelines

Summary 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 as Authorization during Node.js/undici's header dispatch.

  • Detects an own Symbol.iterator on Object.prototype and temporarily removes it during synchronous Request construction and fetch dispatch, skipping the guard when the descriptor is non-configurable.
  • Builds headers as a Headers instance or entries array so the Request constructor never reads Object.prototype[Symbol.iterator] even when the polluted descriptor cannot be removed.
  • Restores the exact property descriptor in a finally block, so in-flight, never-settling, or rejected requests never observe an altered prototype.
  • Restores the descriptor before invoking custom env.fetch or Request implementations; the native fetch is captured once at module load and matched by identity, so a replaced globalThis.fetch is treated as custom while an explicit native globalThis.fetch is 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.fetch and Request, wrapped and replaced globalThis.fetch, non-configurable descriptors, and explicit globalThis.fetch. All unit tests pass with lint clean.

Semantic version impact

Patch version change.

Written for commit 2885b48. Summary will update on new commits.

Review in cubic

@bhumin18
bhumin18 requested a review from jasonsaayman as a code owner August 31, 2026 07:18
@greptile-apps

greptile-apps Bot commented Aug 31, 2026

Copy link
Copy Markdown

Comment thread lib/adapters/fetch.js Outdated
Comment thread lib/adapters/fetch.js Outdated

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 2 files

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread lib/adapters/fetch.js Outdated
Comment thread lib/adapters/fetch.js Outdated
Comment thread lib/adapters/fetch.js Outdated
Comment thread lib/adapters/fetch.js Outdated
Comment thread lib/adapters/fetch.js
Comment thread lib/adapters/fetch.js
Comment thread lib/adapters/fetch.js Outdated

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment thread lib/adapters/fetch.js Outdated
Comment thread lib/adapters/fetch.js Outdated
@jasonsaayman jasonsaayman added commit::fix The PR is related to a bugfix v1x Version 1 labels Sep 1, 2026
Comment thread lib/adapters/fetch.js Outdated
Comment thread lib/adapters/fetch.js Outdated

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment thread lib/adapters/fetch.js Outdated
Comment thread tests/unit/adapters/fetch.test.js
Comment thread lib/adapters/fetch.js
Comment thread lib/adapters/fetch.js Outdated
Comment thread lib/adapters/fetch.js Outdated

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment thread tests/unit/adapters/fetch.test.js
Comment thread lib/adapters/fetch.js Outdated

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment thread lib/adapters/fetch.js Outdated
Comment thread lib/adapters/fetch.js Outdated
Comment thread lib/adapters/fetch.js Outdated
Comment thread lib/adapters/fetch.js Outdated
@greptile-apps

greptile-apps Bot commented Sep 4, 2026

Copy link
Copy Markdown

Want your agent to iterate on Greptile's feedback? Try greploops.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment thread lib/adapters/fetch.js Outdated
Comment thread lib/adapters/fetch.js Outdated
Comment thread lib/adapters/fetch.js

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 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.

T-Rex 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

commit::fix The PR is related to a bugfix v1x Version 1

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants