# Risk map — unjs/ofetch

> Canonical page: https://codevetter.com/unpack/ofetch/risk-map

# Risk map — unjs/ofetch

Scanned commit 1dbc37fd1ceab832fc7c90cad81b1091c95ba563 (2026-07-08). Generated by codevetter codevetter 1.15.0 on 2026-10-02.

Source inspection; upstream code and tests were not executed.

The main review hotspots are URL rewriting, retry replay, abort composition, and error exposure. Several observable boundaries bypass normalized FetchError handling. Documentation also contains compatibility descriptions that differ from this alpha implementation. The following are source observations or explicitly marked hypotheses, not confirmed vulnerabilities.
- FetchError messages include the full request URL, and getters expose request/options/response; logging these objects can expose sensitive query or header data supplied by callers. (inferred) — [src/error.ts#L26-L49](https://github.com/unjs/ofetch/blob/1dbc37fd1ceab832fc7c90cad81b1091c95ba563/src/error.ts#L26-L49) [examples/error-handling.mjs#L7-L12](https://github.com/unjs/ofetch/blob/1dbc37fd1ceab832fc7c90cad81b1091c95ba563/examples/error-handling.mjs#L7-L12) [examples/headers.mjs#L5-L6](https://github.com/unjs/ofetch/blob/1dbc37fd1ceab832fc7c90cad81b1091c95ba563/examples/headers.mjs#L5-L6)
- withBase uses a string prefix check and slash joining rather than origin-aware URL resolution; withQuery splits only at '?', with no explicit fragment handling. — [src/utils.url.ts#L40-L50](https://github.com/unjs/ofetch/blob/1dbc37fd1ceab832fc7c90cad81b1091c95ba563/src/utils.url.ts#L40-L50) [src/utils.url.ts#L69-L102](https://github.com/unjs/ofetch/blob/1dbc37fd1ceab832fc7c90cad81b1091c95ba563/src/utils.url.ts#L69-L102)
- Explicit numeric retries can replay payload methods and reuse transformed bodies; consumed streams and non-idempotent operations therefore need targeted replay validation. (inferred) — [src/fetch.ts#L49-L75](https://github.com/unjs/ofetch/blob/1dbc37fd1ceab832fc7c90cad81b1091c95ba563/src/fetch.ts#L49-L75) [src/fetch.ts#L154-L165](https://github.com/unjs/ofetch/blob/1dbc37fd1ceab832fc7c90cad81b1091c95ba563/src/fetch.ts#L154-L165) [src/utils.ts#L10-L14](https://github.com/unjs/ofetch/blob/1dbc37fd1ceab832fc7c90cad81b1091c95ba563/src/utils.ts#L10-L14)
- Retries retain context.options.signal, then compose another timeout signal; AbortError retry suppression is disabled whenever a timeout option is present. — [src/fetch.ts#L43-L47](https://github.com/unjs/ofetch/blob/1dbc37fd1ceab832fc7c90cad81b1091c95ba563/src/fetch.ts#L43-L47) [src/fetch.ts#L72-L75](https://github.com/unjs/ofetch/blob/1dbc37fd1ceab832fc7c90cad81b1091c95ba563/src/fetch.ts#L72-L75) [src/fetch.ts#L171-L177](https://github.com/unjs/ofetch/blob/1dbc37fd1ceab832fc7c90cad81b1091c95ba563/src/fetch.ts#L171-L177)
- Serialization, timeout construction, JSON parsing, and most hooks lie outside the fetch try/catch, so their exceptions can bypass onRequestError and normalized retry/error handling. — [src/fetch.ts#L110-L177](https://github.com/unjs/ofetch/blob/1dbc37fd1ceab832fc7c90cad81b1091c95ba563/src/fetch.ts#L110-L177) [src/fetch.ts#L180-L198](https://github.com/unjs/ofetch/blob/1dbc37fd1ceab832fc7c90cad81b1091c95ba563/src/fetch.ts#L180-L198) [src/fetch.ts#L215-L253](https://github.com/unjs/ofetch/blob/1dbc37fd1ceab832fc7c90cad81b1091c95ba563/src/fetch.ts#L215-L253)
- isJSONSerializable accesses value.buffer after checking typeof object; its earlier 't === null' condition cannot recognize null, although top-level falsy bodies skip the caller's payload branch. — [src/utils.ts#L17-L32](https://github.com/unjs/ofetch/blob/1dbc37fd1ceab832fc7c90cad81b1091c95ba563/src/utils.ts#L17-L32) [src/fetch.ts#L130-L131](https://github.com/unjs/ofetch/blob/1dbc37fd1ceab832fc7c90cad81b1091c95ba563/src/fetch.ts#L130-L131)
- README names ufo for URL handling and describes response.ok-based failures, while current source uses local URL helpers and specifically rejects statuses 400–599. — [README.md#L78-L80](https://github.com/unjs/ofetch/blob/1dbc37fd1ceab832fc7c90cad81b1091c95ba563/README.md#L78-L80) [README.md#L148-L158](https://github.com/unjs/ofetch/blob/1dbc37fd1ceab832fc7c90cad81b1091c95ba563/README.md#L148-L158) [src/fetch.ts#L1-L3](https://github.com/unjs/ofetch/blob/1dbc37fd1ceab832fc7c90cad81b1091c95ba563/src/fetch.ts#L1-L3) [src/fetch.ts#L242-L246](https://github.com/unjs/ofetch/blob/1dbc37fd1ceab832fc7c90cad81b1091c95ba563/src/fetch.ts#L242-L246)
- Network-sensitive examples include GH_TOKEN authentication and public gist creation; README demonstrates disabling TLS verification, and the release script publishes and pushes. — [examples/headers.mjs#L3-L17](https://github.com/unjs/ofetch/blob/1dbc37fd1ceab832fc7c90cad81b1091c95ba563/examples/headers.mjs#L3-L17) [README.md#L334-L342](https://github.com/unjs/ofetch/blob/1dbc37fd1ceab832fc7c90cad81b1091c95ba563/README.md#L334-L342) [package.json#L21-L21](https://github.com/unjs/ofetch/blob/1dbc37fd1ceab832fc7c90cad81b1091c95ba563/package.json#L21-L21)

Every claim links to its cited files at the pinned commit. Citations identify source evidence; they do not establish runtime correctness. Independent CodeVetter scan — not reviewed by upstream maintainers.

## Public product links

- [CodeVetter](https://codevetter.com/)
- [Download](https://codevetter.com/download)
- [Documentation](https://codevetter.com/docs/)
- [Source](https://github.com/Codevetter/codevetter)
