Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

Inbox refuses all reverse-proxy requests: x-forwarded-for treated as tailnet exposure (breaks local proxies)

Chiusa Adatta ai principianti
#1,867 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
2/5
Tempo stimato
1-3 ore
Idoneità per principianti
76/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
node.js, typescript
Ambito
backend, security

Direzione di ricerca

Inizia individuando il gestore delle richieste inbox che definisce SERVE_HEADERS e chiama localOnly(), poi leggi come vengono usati il controllo dell’header Host e lo stato tailnetPublished. Riproduci il 403 segnalato con un header x-forwarded-for in una richiesta loopback e confrontalo con una richiesta senza quell’header. Il lavoro è concluso quando le richieste del proxy locale funzionano e la protezione tailnet continua a comportarsi come previsto.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

What happened

Since the 0.28.9+ security hardening ("hostname check on every server" / tailnet detection), the Inbox's localOnly check treats any request carrying an x-forwarded-for header as tailnet exposure and refuses it:

var SERVE_HEADERS = ["tailscale-headers-info", "tailscale-user-login", "x-forwarded-for"];
// ...
if (SERVE_HEADERS.some((name) => req.headers.has(name))) {
  tailscale.noteServedRequest();
  return Promise.resolve(localOnly());
}

Response: {"error":"This answers only on this computer, not over the tailnet.","code":"local_only"} (403).

Why this is a problem

Every reverse proxy adds x-forwarded-for — it's standard proxy behavior, not a Tailscale signature. A purely local proxy chain (loopback → local HTTPS front-end → loopback inbox) gets 403'd even though the request never left the machine. This breaks:

  • local HTTPS front-ends with named domains (e.g. portless .localhost aliases — my case: inbox.localhost → 127.0.0.1:<port>)
  • nginx/caddy local setups
  • any dev server proxying to the inbox

Verified by sending x-forwarded-for: 1.2.3.4 on an otherwise plain loopback request — 403 local_only; without the header, 200.

Suggested fix

The two tailscale-* headers are genuinely Tailscale-serve-specific and are the right signal. x-forwarded-for alone is not — it only becomes meaningful when tailscale serve is the thing adding it. Options:

  1. Drop x-forwarded-for from SERVE_HEADERS (the Host-header guard already protects loopback-only endpoints).
  2. Only treat x-forwarded-for as tailnet-exposure when tailscale is actually publishing (the inbox already tracks tailnetPublished state).
  3. Check that x-forwarded-for's value is a non-loopback address (tailscale serve forwards the real client IP; a local proxy forwards 127.0.0.1).

Workaround in the meantime

A tiny local proxy that strips x-forwarded-for (and the other forwarded headers) in front of the inbox.

Versions: plannotator 0.28.16 (darwin-arm64), inbox started via plannotator inbox --background.

Lingua principale
TypeScript
Stelle
8.7k
Fork
649
Merge medio
6h
PR unite (30g)
514

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di backnotprop/plannotator

Tutte le issue di backnotprop/plannotator

Issue simili

Altre issue su TypeScript

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.