Skip to content

openApiTools: optional pinned-DNS private-address check (follow-up to N13a) #291

Description

@LinuxDevil

Goal

Let openApiTools() (src/tools/openapi/) refuse private destinations with the same pinned DNS lookup that http_request and web_fetch use since #255 / #277, for applications whose OpenAPI base URL (or the document URL) is not fully under their control.

Current state

  • openApiTools() sends every request (and the document fetch) through options.fetch ?? fetch, with no private-address check. docs/openapi-tools.md ("Security", bullet "No private-address check") says so and tells users to put a proxy in front or pass their own fetch.
  • src/security/privateAddress.ts (added by [N13a] web_fetch built-in with pinned-DNS SSRF checks; http_request no longer open to DNS rebinding #277) has isPrivateAddress(), resolvePublicAddresses() and pinnedLookup(); http.ts and webFetch.ts use it through an undici Agent({ connect: { lookup: pinnedLookup({ allowPrivate }) } }). The module is internal: nothing is exported from the package root.

Why it was not done in #277

It is not a small, contained change; it needs public API decisions:

  • Default. openApiTools deliberately allows http: for localhost, 127.0.0.1, [::1], and base URLs are developer-configured, often internal APIs on private addresses. Turning the check on by default would break those; turning it on by opt-in needs a new option (e.g. privateAddresses: 'allow' | 'refuse' plus allowPrivate host patterns).
  • Interaction with the fetch option (a user-supplied fetch cannot be given a dispatcher portably), and with the document fetch in loadDocument().
  • Runtime: undici and node:dns are Node only; check whether openApiTools is meant to work on Workers / edge before adding them to its path.
  • Alternatively export a public helper (e.g. createPinnedFetch({ allowPrivate })) that users pass as fetch, which also serves custom tools.

Scope

Decide one of the above, implement it with a test that a base URL resolving to a private address (stubbed resolver) is refused and that a rebinding name (public first, 127.0.0.1 second) never reaches a local server, and update the "No private-address check" bullet in docs/openapi-tools.md plus a CHANGELOG entry.

Found while finishing #255 (PR #277).

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    round-2Round 2 plan ticket

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions