Skip to content

Security: fetch-retry final log still includes init.body — leaks refresh tokens after #598 removed headers #635

Description

@JoelCode

Version

@nuxtjs/supabase 2.0.9 (current main)

Summary

#598 / PR #599 removed headers from the final-failure log in src/runtime/utils/fetch-retry.ts, but the rest of init is still logged — and that includes init.body:

if (attempt === retries) {
  const { headers: _headers, ...safeInit } = init ?? {}
  console.error(`Error fetching request ${req}`, error, safeInit)
  throw error
}

For requests supabase-js sends to /auth/v1/token, init.body contains credentials:

  • ?grant_type=refresh_token{"refresh_token":"..."}
  • ?grant_type=password → the user's email and password

So the body has the same failure mode #598 fixed for headers: any auth request that fails all 3 retries (network blip, device offline, rate limit) logs the credential via console.error, and any runtime that captures console output persists it — Sentry's default console breadcrumbs attach it to captured events, and the same applies to Cloudflare Workers Observability, Vercel log drains, and stdout shipping.

A leaked refresh token is a live session: it can be exchanged for a fresh access + refresh token pair by anyone with read access to the logging destination.

Reproduction

Any request with a sensitive body that fails 3 times, e.g. go offline (or block *.supabase.co) with a session due for refresh; the final attempt logs {"method":"POST","body":"{\"refresh_token\":\"...\"}"}.

Proposed fix

Extend the #599 destructure by one key:

const { headers: _headers, body: _body, ...safeInit } = init ?? {}

The body is never useful for diagnosing a fetch failure (the error carries the cause), so there's nothing to redact selectively.

Happy to open a PR.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions