Skip to content

fix: malformed http urls#11000

Merged
jasonsaayman merged 10 commits into
v1.xfrom
fix/malformed-http-urls
Jun 11, 2026
Merged

fix: malformed http urls#11000
jasonsaayman merged 10 commits into
v1.xfrom
fix/malformed-http-urls

Conversation

@jasonsaayman

@jasonsaayman jasonsaayman commented Jun 10, 2026

Copy link
Copy Markdown
Member

Summary

Reject malformed http: and https: URLs that omit // before adapter URL normalisation, returning AxiosError with ERR_INVALID_URL instead of silently normalising invalid input.

This also tightens related security coverage around polluted inherited config values, upload/content length limits, data URL size estimation, FormData recursion depth, and local proxy bypass matching.

Linked issue

Closes #7315

Changes

  • Reject malformed HTTP(S) URLs such as https:example.com and http:/example.com across core URL building and adapters.
  • Ignore inherited prototype-polluted config/header/auth/params values in affected request paths.
  • Enforce upload and content length limits more consistently in fetch and HTTP adapters.
  • Add recursion depth protection for formDataToJSON.
  • Treat unspecified local addresses like 0.0.0.0 and IPv6 :: as local for NO_PROXY matching.
  • Add focused regression coverage and pre-release changelog/docs tracking.

Checklist

  • Tests added or updated
  • Docs/types updated if public API changed (index.d.ts and index.d.cts) - N/A, no public API or type change
  • No breaking changes

Summary by cubic

Reject malformed HTTP(S) URLs that omit “//” and harden stream/proxy safety. Size limits are now enforced consistently across fetch, Node HTTP/HTTPS/HTTP2, and custom fetch, and header/config reads ignore prototype pollution.

Description

  • Summary of changes
    • Reject malformed http:/https: URLs before adapter normalization; throw AxiosError ERR_INVALID_URL and preserve config.
    • Read nested config safely via utils.getSafeProp (auth, headers, params, serializer, proxy, method, agents, limits, timeouts, decompress); ignore values injected on Object.prototype.
    • Ignore inherited Symbol.iterator for header sources; only own iterators are used for request and response headers.
    • Enforce maxBodyLength on streamed uploads in fetch, native HTTP/HTTPS, HTTP/2, and custom fetch; never trust caller-declared Content-Length. If the Request impl doesn’t support stream bodies, throw ERR_NOT_SUPPORT instead of forcing a stream.
    • Enforce maxContentLength on streamed responses with declared-length pre-checks; accept plain-object response headers via AxiosHeaders.
    • Align FormData recursion limits using DEFAULT_FORM_DATA_MAX_DEPTH (100) and guard both {} metatokens and formDataToJSON path parsing; throw ERR_FORM_DATA_DEPTH_EXCEEDED.
    • Treat 0.0.0.0 and IPv6 :: (including compressed/all-zero forms) as local for NO_PROXY.
    • Compute exact decoded size for percent-encoded data: URLs.
    • Helpers: bodyless method helpers ignore inherited data; getUri ignores inherited serializer options.
  • Reasoning
    • Block silent URL normalization and prototype pollution in untrusted inputs.
    • Apply consistent, stream-aware limits across transports to prevent DoS/overflows.
  • Additional context

Docs

Please update /docs/:

  • Note that malformed http:/https: URLs missing // now throw ERR_INVALID_URL.
  • Document the shared FormData depth guard (DEFAULT_FORM_DATA_MAX_DEPTH = 100) and ERR_FORM_DATA_DEPTH_EXCEEDED.
  • Mention stricter local address handling for NO_PROXY (0.0.0.0, ::) and consistent stream size enforcement; fetch throws ERR_NOT_SUPPORT when its Request does not support stream bodies.

Testing

  • Added/updated tests:
    • Malformed URL rejection in fetch, Node HTTP/HTTP2, and XHR; config preserved.
    • Pollution-safe reads for nested options; bodyless helpers ignore inherited data; getUri ignores inherited serializer options.
    • Ignore inherited Symbol.iterator for request/response headers; iterable sources must have own iterators.
    • maxBodyLength on streamed uploads across fetch, native HTTP/HTTPS, HTTP/2, and custom fetch; declared Content-Length cannot bypass limits; throw ERR_NOT_SUPPORT when Request lacks stream support.
    • maxContentLength on streamed responses with declared-length pre-checks; plain-object headers supported via AxiosHeaders.
    • FormData depth guard for {} metatokens and formDataToJSON parsing; throws ERR_FORM_DATA_DEPTH_EXCEEDED.
    • Exact decoded size for percent-encoded data: URLs.
    • NO_PROXY matching for 0.0.0.0 and IPv6 :: (including compressed forms and ports).
  • Coverage spans unit, browser, and adapter tests; no additional tests needed.

Semantic version impact

Patch: bug fixes and security hardening. Invalid inputs that were previously normalized now throw ERR_INVALID_URL; no API changes.

Written for commit d454282. Summary will update on new commits.

Review in cubic

@jasonsaayman jasonsaayman self-assigned this Jun 10, 2026
@jasonsaayman jasonsaayman changed the title Fix/malformed http urls fix: malformed http urls Jun 10, 2026

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

1 issue found and verified against the latest diff

Confidence score: 3/5

  • lib/utils.js’s prototype-chain walk can enter an infinite loop on crafted Proxy objects because there’s no cycle detection, which can hang execution or cause a denial-of-service path if untrusted objects reach this code — add visited-object tracking (or a max traversal depth) and a targeted test for cyclic/proxy chains before merging.

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

Re-trigger cubic

Comment thread lib/utils.js

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

1 issue found across 4 files (changes from recent commits).

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

Re-trigger cubic

Comment thread lib/helpers/toFormData.js Outdated
@jasonsaayman

Copy link
Copy Markdown
Member Author

@cubic-dev-ai please review in depth

@cubic-dev-ai

cubic-dev-ai Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

@cubic-dev-ai please review in depth

@jasonsaayman I have started the AI code review. It will take a few minutes to complete.

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

3 issues found across 29 files

Confidence score: 3/5

  • In lib/adapters/fetch.js, the stream maxBodyLength wrapping path ignores supportsRequestStream, so environments without request stream support can still be handed a ReadableStream, leading to request failures/regressions for streamed uploads—gate that wrapping logic on supportsRequestStream before merging.
  • In lib/utils.js (isSafeIterable), reading thing[Symbol.iterator] before pollution checks can still trigger polluted Object.prototype accessors, which may throw or execute unintended code paths at runtime—move the safety checks ahead of property access (or use a safe lookup pattern) to de-risk this.
  • In lib/helpers/shouldBypassProxy.js (isIPv6Unspecified), not recognizing compressed all-zero IPv6 forms can make equivalent unspecified addresses bypass proxy rules inconsistently, causing surprising networking behavior—normalize/expand IPv6 unspecified matching and add coverage for compressed variants.

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

Re-trigger cubic

Comment thread lib/helpers/shouldBypassProxy.js Outdated
Comment thread lib/adapters/fetch.js
Comment thread lib/utils.js Outdated
@jasonsaayman jasonsaayman merged commit 32fc489 into v1.x Jun 11, 2026
29 checks passed
@jasonsaayman jasonsaayman deleted the fix/malformed-http-urls branch June 11, 2026 06:36
ModyQyW added a commit to uni-helper/uni-network that referenced this pull request Jun 15, 2026
yassertawfik4 added a commit to yassertawfik4/axios that referenced this pull request Jun 22, 2026
The ERR_INVALID_URL error thrown for http:/https: URLs missing the
"//" after the protocol (added in axios#11000) only said `Invalid URL:
missing "//" after protocol`, with no indication of which value was
rejected. Users upgrading to 1.18.0 hit this without a clear cause
(axios#11008).

Include the offending URL (in its control-character-normalized form)
in the message, e.g. `Invalid URL "https:example.com": missing "//"
after protocol`. Behavior is otherwise unchanged: the same inputs are
still rejected with the same code.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Normalization of url cause an ssrf security bypass

1 participant