Skip to content

502 Unsafe upstream redirect when Meta Pixel's /tr endpoint returns 302 #885

Description

@i-kyvatskyi

🐛 The bug

Env
@nuxt/scripts@1.3.5
nuxt@4.4.8

Config:

scripts: {
    registry: {
      googleTagManager: {
        id: GTM_ID,
        trigger: 'onNuxtReady',
        bundle: false,
      },
      metaPixel: {
        id: META_PIXEL_KEY,
        trigger: 'onNuxtReady',
      },
      googleAnalytics: {
        id: GOOGLE_ANALYTICS_KEY,
        trigger: 'onNuxtReady',
      },
    },
  },

Intermittently, POST /_scripts/p/www.facebook.com/tr/ fails with a 502 Unsafe upstream redirect because Facebook responds with a 302 for this particular request, and the first-party proxy handler refuses to follow it.

In proxy-handler.ts, the fetch to the upstream is always made with redirect: manual, and any 3xx response other than 304 throws a 502:

const requestInit: RequestInit = {
  ...
  redirect: 'manual',
}
...
if (response.status >= 300 && response.status < 400 && response.status !== 304) {
  throw createError({
    statusCode: 502,
    statusMessage: 'Unsafe upstream redirect',
    message: 'Proxy upstream returned a redirect that was not followed',
  })
}

I understand this is intentional — following the Location header would mean sending a request to a host that was never validated against the domain allowlist (SSRF risk), so blindly following it isn't safe. I noticed image-proxy.ts already has a followRedirects option that re-validates each hop against the same allowlist before following it — is something similar planned/possible for the event-collection proxy handler used by registry scripts like Meta Pixel?

Image Image

🛠️ To reproduce

🌈 Expected behavior

ℹ️ Additional context

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions