Repository navigation
v2.3.0 — DNS-rebinding SSRF closed; importer redirects checked per hop
Security release: closes a DNS-rebinding SSRF class across every outbound
HTTP call, plus unchecked redirect following in the importers
(PRs #83, #84, #85). Upgrade recommended.
Security
- DNS rebinding. Every caller checked the resolved IP and then called
fetch(hostname), which resolved again, so a TTL-0 domain could answer
public for the check and127.0.0.1(or cloud metadata) for the
connection. On the credential paths this delivered the stored bearer
token (replay), the refresh token and client secret (OAuth refresh),
and the GitHub token (GitHub spec import) to the internal host. All
outbound HTTP now goes throughsrc/net/transport.ts, which runs the
private-range check inside the connection's own DNS lookup, so the
address checked is the address connected to. Every address in a DNS
answer must be public. - Unchecked redirects. The GitHub, SwaggerHub and APIs.guru list
importers andapitap import <url>followed redirects with no per-hop
check, so any spec URL could redirect to169.254.169.254. Redirects
are now followed hop by hop through the same check, at most 5, only for
301/302/303/307/308; aLocationwith userinfo is refused; and
Authorization,CookieandProxy-Authorizationare dropped when a
redirect changes origin. read/peekredirect following had no hop limit (a redirect loop never
ended); it is now capped at 5 (TOO_MANY_REDIRECTS).- More reserved ranges blocked: multicast
224/4, the documentation
ranges,192.0.0/24, IPv4-compatible::/96, and 6to42002::/16.
Changed
peekreports a DNS failure as a transport error (ENOTFOUND,
recommendationerror) instead of "blocked by SSRF protection".- OAuth token refresh no longer follows redirects; a redirecting token
endpoint now fails withToken endpoint returned 30x. - Replay drops captured
content-length,transfer-encoding,
connection,keep-aliveandhostheaders and lets the connection
compute them (a captured length went stale once a body template
expanded). read/peekbodies: the size cap counts decompressed bytes and stops
reading at the cap; a cut never splits a UTF-8 character; stacked
Content-Encodingis decoded; HEAD and redirects return as soon as
headers arrive; the response header limit is 64 KB.- For contributors: tests that intercept outbound HTTP stub
transport.fetch, notglobalThis.fetch.