openfetch is a thin fetch wrapper. Callers supply URLs, headers, and bodies. The library does not implement its own TLS, DNS, or full SSRF filtering.
-
Axios-class proxy CVEs (e.g. CVE-2025-62718 /
NO_PROXYnormalization) — openfetch does not implement axios-styleHTTP_PROXY/HTTPS_PROXY/NO_PROXYmatching. Outbound routing follows the host runtime’sfetch(and any platform proxy). Those CVEs therefore do not map to openfetch code paths; policy still belongs at the app, proxy, or mesh layer. -
Network trust — You choose endpoints. Blocking private IPs, metadata hosts, or open redirects is an application concern for partially trusted URLs.
-
Secrets —
toShape()/toJSON()onOpenFetchErroromitconfig.authand, by default, omit responsedataandheaders(passincludeResponseData: true/includeResponseHeaders: trueonly for trusted diagnostics). The liveErrorinstance may still carry fullconfigandresponse; never expose it raw to untrusted clients. By default,toShape()redacts common sensitive query parameters in the serializedurl(for exampletoken,code,password); useredactSensitiveUrlQuery: falseonly for trusted diagnostics. Thedebug()plugin applies the same redaction to logged URLs. -
Supply chain — Install this package from npm or a verified Git tag; verify integrity with your package manager.
When a URL (or part of it) comes from user input or another untrusted source on Node.js, Deno, edge workers, or similar, fetch can reach internal addresses (SSRF), cloud metadata endpoints, or other restricted networks.
Mitigations (combine as appropriate):
- Allowlist hostnames or full URL prefixes your backend is allowed to call.
- Block literal private IPs — Call
assertSafeHttpUrl(url)before issuing the request, or setassertSafeUrl: trueoncreateClient/ per request so the fully resolved URL is checked automatically inside the dispatcher. The helper rejectshttp/httpsURLs whose host is a loopback, private, link-local, or IPv4-mapped private address. On runtimes that use the WHATWG URL parser (including Node.js), hosts written as decimal integers, hex/octal IPv4 segments, or shorthand forms (for example127.1) are normalized to dotted-quad literals beforehostnameis read;assertSafeHttpUrlstill applies its checks to that normalized host. It does not stop a public hostname from resolving to an internal IP (DNS rebinding); resolve and validate in a controlled resolver or use an outbound proxy. - Egress controls — Route outbound HTTP through a proxy or service mesh that enforces policy.
createCacheMiddleware builds a cache key from METHOD fullUrl (plus optional custom key). By default, authorization and cookie request header values are folded into the key (and any extra names you pass in varyHeaderNames are merged with those two), so authenticated GETs do not share entries across different credentials.
Risk: If you set varyHeaderNames: [] explicitly, the key is URL-only; the first successful response for that URL can be served to other callers until the entry expires.
Mitigations:
- Omit
varyHeaderNames(secure default), or pass additional header names (they are merged withauthorizationandcookie), or - Provide a custom
keythat incorporates a stable tenant or session identifier, or - Use
appendCacheKeyVaryHeaderswhen building a custom key.
The middleware emits a one-time console.warn the first time it sees Authorization or Cookie while varyHeaderNames was explicitly set to [] and no custom key is set. Suppress with suppressAuthCacheKeyWarning: true when that configuration is intentional (for example anonymous-only CDN).
By default, createRetryMiddleware retries network/parse failures and configured HTTP error statuses only for GET, HEAD, OPTIONS, and TRACE, to reduce duplicate side effects (for example double charges on POST).
Set retry.retryNonIdempotentMethods: true on the client defaults or per request when you explicitly want retries for POST, PUT, PATCH, or DELETE.
mergeConfigdrops own properties named__proto__,constructor, andprototypeon the merged config,headers,retry, andmemoryCacheto reduce prototype pollution from untrusted config objects.- Invalid header values (for example containing CR/LF) are rejected by the runtime
fetchimplementation rather than being sent on the wire.
Email or open a private security advisory on the repository if you believe you have found a vulnerability. Please avoid public issues for undisclosed security defects until they are addressed.
From the repository root (after npm install):
npm run test:security
npm audittest:security runs regression-style checks (config merging and prototype-pollution keys, header injection attempt, error shape, cache and varyHeaderNames behavior, assertSafeHttpUrl including Node URL normalization cases, URL builder performance). It is not a full penetration test or formal audit.
Optional static analysis (Semgrep): Semgrep is not an npm dependency of this package. To scan src/ locally, use a virtualenv or pipx, for example:
python3 -m venv .venv && .venv/bin/pip install semgrep
.venv/bin/semgrep scan --config p/typescript --config p/javascript srcReview any findings manually; rules can produce false positives on thin wrappers.