fix(ssrf): validate hostname even when pinDns is disabled

When pinDns=false was set to avoid undici dispatcher corruption of
FormData bodies, resolvePinnedHostnameWithPolicy was skipped entirely,
removing SSRF hostname/private-IP validation.

Now the pinDns=false path runs hostname validation as a preflight
before creating the non-pinned dispatcher, preserving defense-in-depth.

Also renames a stale test description per Greptile review feedback.
This commit is contained in:
GodsBoy
2026-04-11 12:59:16 +02:00
committed by Ayaan Zaidi
parent ed356d740d
commit c159d22b34
2 changed files with 8 additions and 1 deletions

View File

@@ -318,6 +318,13 @@ export async function fetchWithSsrFGuard(params: GuardedFetchOptions): Promise<G
if (canUseTrustedEnvProxy) {
dispatcher = createHttp1EnvHttpProxyAgent();
} else if (params.pinDns === false) {
// Validate hostname against SSRF policy even without DNS pinning.
// Callers opt out of the undici pinned dispatcher (e.g. to avoid
// FormData corruption) but still need private-IP / blocklist checks.
await resolvePinnedHostnameWithPolicy(parsedUrl.hostname, {
lookupFn: params.lookupFn,
policy: params.policy,
});
dispatcher = createPolicyDispatcherWithoutPinnedDns(params.dispatcherPolicy);
} else {
const pinned = await resolvePinnedHostnameWithPolicy(parsedUrl.hostname, {

View File

@@ -247,7 +247,7 @@ describe("fetchWithTimeoutGuarded", () => {
);
});
it("forwards explicit pinDns overrides to transcription requests", async () => {
it("always passes pinDns: false to the SSRF guard for transcription requests", async () => {
fetchWithSsrFGuardMock.mockResolvedValue({
response: new Response(null, { status: 200 }),
finalUrl: "https://example.com",