InstaTunnel
Navigationsmenu umschalten
Tutorial
10 min read
23 views

Weitergeleitete Header sind kein vertrauenswürdiger Input: X-Forwarded-For, Proto und Host hinter einem Tunnel

Hinter einem Tunnel sind X-Forwarded-For, Proto und Host nicht verlässliche Eingaben. Erfahren Sie die richtigen trustProxy-Einstellungen für Express, Fastify, Django und Rails.

IT
InstaTunnel Team
Published by the InstaTunnel team | Editorial policy
Weitergeleitete Header sind kein vertrauenswürdiger Input: X-Forwarded-For, Proto und Host hinter einem Tunnel

Quick answer

Weitergeleitete Header sind kein vertrauenswürdiger Input hinter einem Tunnel: quick answer

If free tunnel limits interrupt your workflow, compare session length, stable URLs, concurrent tunnels, and paid-plan pricing before choosing a localhost tunnel tool.

What free tunnel limits should developers check first?

Check session duration, URL stability, concurrent tunnels, custom subdomains, bandwidth or request limits, and whether webhook callbacks survive restarts.

How does InstaTunnel handle longer development sessions?

InstaTunnel Free is designed around 24-hour sessions, with Pro available for higher limits and MCP endpoint tunnel workflows.

Wenn du eine App hinter einem Tunnel betreibst, bestimmen drei Anfrage-Header, was dein Code glaubt. X-Forwarded-For sagt, wer anruft, X-Forwarded-Proto sagt, ob die Anfrage HTTPS war, und X-Forwarded-Host sagt, welchen Hostnamen der Aufrufer angefragt hat. Konfiguriere trustProxy falsch und du bekommst eines von zwei Fehlern. Der harmlose Fall ist eine Weiterleitungs-Schleife oder ein Rate-Limiter, der nur einen Besucher sieht. Der schädliche Fall ist ein Angreifer, der die Werte wählt, auf die deine Sicherheitsprüfungen vertrauen.

2026 machte den zweiten Fehler konkret. Fastify hat innerhalb von fünf Monaten zwei CVEs zu genau diesem Problem veröffentlicht, und das proxy-addr-Paket hinter Expresss req.ip hatte einen eigenen kritischen Vertrauens-Subnetz-Fehler. Diese Anleitung erklärt, was ein Tunnel wirklich sendet, warum Apps es falsch lesen, und welche Einstellungen in Express, Fastify, Django und Rails funktionieren.

Was ein Tunnel tatsächlich sendet

Ein Tunnel verändert die Form der Verbindung. Die TLS-Sitzung des Besuchers endet am Edge des Anbieters. Der Edge leitet die Anfrage durch den Tunnel an einen Agenten auf deinem Rechner weiter, und der Agent stellt eine normale HTTP-Anfrage an deine App auf localhost. Deine App sieht niemals das Socket des Besuchers. Die Verbindung, die sie sieht, stammt vom Agenten, normalerweise 127.0.0.1, und alles Weitere über den Besucher kommt als Header an.

Die Dokumentation des Anbieters beschreibt diese Header:

  • ngrok fügt die Client-IP zu X-Forwarded-For hinzu und das Anforderungs-Schema zu X-Forwarded-Proto. Falls der Besucher bereits eines der Header gesendet hat, hängt ngrok einen neuen Wert anstelle des alten an, und seine Dokumentation empfiehlt, den letzten Wert zu lesen. Für X-Forwarded-Host behält ngrok den Header des Besuchers bei, wenn einer existiert, ansonsten verwendet es den Host der Anfrage.
  • Cloudflare sendet die Besucheradresse in CF-Connecting-IP und empfiehlt sie gegenüber X-Forwarded-For. Es hängt die Verbindungsadresse an jedes vorhandene X-Forwarded-For an, sodass Werte, die der Besucher eingegeben hat, links bleiben. Ein öffentliches cloudflared-Issue zeigt eine Anfrage mit einer gefälschten Liste, die am Ursprung mit der echten Adresse am Ende ankommt.

Das Muster ist überall dasselbe: Edge-Knoten hängen Werte an, sie werden nicht bereinigt. Was auch immer ein Besucher eingegeben hat, befindet sich immer noch im Header, den deine App empfängt. Nur die Einträge, die von Hops stammen, die du kontrollierst, können als zuverlässig gelten.

Warum der Rate-Limiter die Tunnel-IP sieht

Die meisten Rate-Limiter verwenden die Socket-Adresse als Schlüssel. Hinter einem Tunnel kommt jede Anfrage vom Agenten auf localhost an, daher landet jeder Besucher im gleichen Bucket. Ein lauter Client erschöpft das Kontingent für alle, und eine IP-Whitelist blockiert den gesamten Traffic oder lässt ihn zu.

Die Lösung besteht darin, deinem Framework mitzuteilen, welche Verbindungsadresse ein vertrauenswürdiger Proxy ist, damit es die Client-Adresse sicher aus X-Forwarded-For auslesen kann. Die falsche Lösung ist, den ersten Wert des Headers selbst auszulesen. Die MDN-Richtlinien sind deutlich: Jede sicherheitsrelevante Nutzung von X-Forwarded-For, z.B. für Ratenbegrenzung oder IP-Zugriffskontrolle, darf nur Adressen verwenden, die von einem vertrauenswürdigen Proxy hinzugefügt wurden; und die am linken Rand stehenden Werte eignen sich nur dort, wo Spoofing keine Auswirkungen hat. Ein Go-Problem, das Ratenbegrenzungen untersuchte, zeigte denselben Fehler, wobei die links stehende Parsung es Clients ermöglichte, ihre Grenzwerte zu umgehen.

Warum falsche Protokoll-Erkennung Redirect-Schleifen verursacht

TLS endet am Edge, daher erhält deine App unverschlüsseltes HTTP. Wenn sie HTTPS erzwingt, sieht sie eine unsichere Anfrage und antwortet mit einer Weiterleitung zu https://. Der Browser folgt, die Anfrage geht erneut durch den Edge, und deine App sieht erneut HTTP. Die Schleife endet nie.

Django’s eigene Dokumentation sagt das direkt: Wenn SECURE_SSL_REDIRECT endlose Redirects verursacht, kann die Seite vermutlich nicht erkennen, welche Anfragen hinter einem Proxy sicher sind, und SECURE_PROXY_SSL_HEADER ist die Lösung. Rails dokumentiert die gleiche Falle und bemerkt, dass hinter einem SSL-terminierenden Proxy die weitergeleitete Anfrage wie HTTP aussieht, was Redirects und Cookiesicherheit zum falschen Schema sendet.

Bevor du irgendeine Einstellung änderst, gib aus, was tatsächlich ankommt. Ein 2024er Beitrag fand heraus, dass X-Forwarded-Proto durch einen Cloudflare-Tunnel http blieb und stattdessen den CF-Visitor-Header verwendete. Anbieter ändern das Verhalten, also verifiziere es mit deiner eigenen Anfrage.

Die Regel: Vertraue zuerst der Verbindung, dann dem Header

X-Forwarded-* Header sind Ansprüche, keine Fakten. MDN besagt, dass, wenn ein Server direkt aus dem Internet erreichbar ist, auch wenn er hinter einem vertrauenswürdigen Proxy sitzt, kein Teil der Liste X-Forwarded-For vertrauenswürdig ist. Der sichere Algorithmus hat zwei Schritte:

  1. Prüfe, ob die Verbindungsadresse zu einem Proxy gehört, dem du vertraust.
  2. Lies erst dann den Header von rechts, überspringe vertrauenswürdige Proxys. Die erste untrusted-Adresse ist der Client.

Frameworks, die Schritt Eins überspringen oder ihn schlecht implementieren, gehören zu denen, die die 2026er Warnungen verursacht haben.

Der CVE-Weg 2026

CVE-2026-3635 (Fastify, veröffentlicht am 23. März 2026). In Fastify 5.8.2 und älteren Versionen lässt ein restriktiver trustProxy-Wert, wie eine IP, ein Subnetz, eine Hop-Anzahl oder eine benutzerdefinierte Funktion, trotzdem request.protocol und request.host aus X-Forwarded-Proto und X-Forwarded-Host von jeder Verbindung lesen, einschließlich untrusted Verbindungen. Ein Angreifer, der den Server direkt erreicht, könnte beide fälschen. Die Advisories führen HTTPS-Verstöße, sichere Cookie-Flags, CSRF-Origin-Prüfungen, URL-Konstruktion und hostbasierte Routing als betroffen auf. Der CVSS-Wert ist 6.1, und der Fix ist Fastify 5.8.3. Mit trustProxy: true verhält sich das Verhalten so, wie erwartet, da diese Einstellung alles vertraut.

CVE-2026-16732 (Fastify, veröffentlicht am 18. August 2026). Die 5.8.3-Wächterprüfung prüfte die Verbindungsadresse, was für IP, CIDR und Funktionsformen funktioniert. Die numerische Hop-Anzahl-Form kompiliert zu einer Prädikatsbedingung, die die Adresse ignoriert, sodass der Wächter immer durchkam. Versionen 5.8.3 bis einschließlich 5.12.1 blieben verwundbar. Betroffenheit entspricht dem übergeordneten CVE und fügt Cache-Verfälschungen hinzu. Fastify 5.12.1 deaktiviert numerische trustProxy zur Laufzeit und entfernt es aus den TypeScript-Typen. Der Workaround der Advisories ist ein IP-, CIDR- oder Funktionswert, plus sicherstellen, dass der Ursprung nur über die Proxy-Kette erreichbar ist.

CVE-2026-90711 (proxy-addr, veröffentlicht am 15. September 2026). proxy-addr ermittelt Client-Adressen hinter vertrauenswürdigen Proxies und stützt sich auf Expresss req.ip und req.ips. In den Versionen 1.1.0 bis 2.0.7 wurde ein Vertrauens-Subnetz, geschrieben in IPv4-mapped IPv6-Form mit einem IPv4-großen Präfix, wie z. B. ::ffff:10.0.0.0/8 statt ::ffff:10.0.0.0/104, still akzeptiert und vertraute jeder IPv4-Adresse. Jeder Client konnte dann ein beliebiges X-Forwarded-For liefern, wodurch IP-Zugriffskontrollen, Ratenbegrenzung, Geolocation und Audit-Logs umgangen wurden. Der CVSS-Wert beträgt 9.1, der Fix ist 2.0.8. Das Fastify-Plugin übernahm es als CVE-2026-92395, betraf @fastify/proxy-addr 3.0.0 bis 5.1.0, behoben in 5.1.1.

Die Advisories teilen eine Vorbedingung: Der Angreifer muss deine App erreichen, ohne durch den Proxy zu gehen. Bei einem Tunnel klingt das unwahrscheinlich, bis du prüfst, wie dein Dev-Server gebunden ist. Ein Server, der auf 0.0.0.0 hört oder ein Container mit einem veröffentlichten Port ist aus deinem LAN erreichbar, ohne dass ein Tunnel beteiligt ist. Das ergibt sich aus der Funktionsweise der Bindung, nicht aus den Advisory-Empfehlungen, aber es erklärt, warum „es ist nur ein Dev-Tunnel“ kein echter Trost ist. Binde an 127.0.0.1.

Korrekte Vertrauenseinstellungen pro Framework

Express

Express setzt trust proxy standardmäßig auf false, daher ist req.ip die Socket-Adresse und jeder Besucher wirkt wie der Agent. Wenn du es auf true setzt, behebst du das, aber es entsteht ein anderes Problem: Express behandelt dann den am linken Rand stehenden X-Forwarded-For-Eintrag als Client, und seine Dokumentation warnt, dass der zuletzt vertraute Proxy die Weiterleitungs-Header überschreiben muss oder Clients jeden Wert liefern können. Da Tunnel Werte anhängen, ist true die falsche Wahl.

Vertraue stattdessen der Adresse des Agenten:

// Agent runs on the same machine
app.set('trust proxy', 'loopback');

// Agent in a container: trust that network only
app.set('trust proxy', ['loopback', '172.18.0.0/16']);

Express liest X-Forwarded-For nur von der rechten Seite, wenn der Socket-Partner vertrauenswürdig ist. Mit dieser Einstellung folgt req.protocol X-Forwarded-Proto, req.hostname folgt X-Forwarded-Host, und req.ip ist die erste untrusted-Adresse von der rechten Seite. Aktualisiere proxy-addr auf 2.0.8 oder später (npm ls proxy-addr zeigt, welche Kopie du hast) und prüfe sorgfältig alle IPv4-mappte IPv6-Subnets.

Fastify

Upgrade auf 5.12.1 oder neuer und verwende keine numerischen Werte mehr:

const fastify = require('fastify')({
  trustProxy: ['127.0.0.1', '::1'] // IPs or CIDRs of the agent only
});

Fastify’s aktuelle Dokumentation bezeichnet außerdem request.ip, request.host und request.protocol als Metadaten der Anfrage, die als untrusted input behandelt werden sollen. Binde den Server an den Loopback, damit die Prüfung nicht umgangen werden kann.

Django

Django hat kein Äquivalent zu trust proxy für Client-IPs. REMOTE_ADDR ist der Socket-Partner, daher brauchst du eine klare Entscheidung. Zwei Einstellungen sind für das Schema wichtig:

# settings.py
SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")
SECURE_SSL_REDIRECT = True

Djangos eigene Warnung gilt: Setze dies nur, wenn der Proxy X-Forwarded-Proto von eingehenden Anfragen entfernt, einschließlich Werte, die als komma-getrennte Liste ankommen. Ein Tunnel, der Werte anhängt statt zu überschreiben, erfüllt diese Bedingung nicht, also verifiziere es mit dem Header-Test unten. Auf der Server-Ebene vertraut Gunicorn Weiterleitungs-Header standardmäßig nur von 127.0.0.1 über forwarded_allow_ips, und uvicorns --proxy-headers ist standardmäßig aktiv, aber begrenzt auf --forwarded-allow-ips, das standardmäßig 127.0.0.1 ist. Container-Konfigurationen verleiten dazu, * zu setzen; liste stattdessen das Agentennetzwerk. Für Client-IPs unterstützt django-ipware proxy_trusted_ips und proxy_count genau dies.


### Rails

`ActionDispatch::RemoteIp` entfernt vertrauenswürdige Proxies aus der weitergeleiteten Kette und gibt die zuletzt verbleibende Adresse zurück. Die standardmäßig vertraute Liste deckt Loopback- und private Bereiche ab, was zu einem Tunnel-Agenten auf localhost passt. Sie wirft auch `IpSpoofAttackError`, wenn `Client-Ip` und `X-Forwarded-For` widersprechen. Wenn du `config.action_dispatch.trusted_proxies` setzt, übergib ein Array, denn eine Aufzählung ersetzt die Defaults.

Für die Redirect-Schleife bietet Rails `config.assume_ssl = true` an, was dem Server mitteilt, dass der Proxy SSL bereits beendet hat. Verwende es nur, wenn die App ausschließlich über den Tunnel erreichbar ist, da diese Einstellung jede Anfrage als HTTPS behandelt.

## Teste wie ein Angreifer

Sende gefälschte Header direkt an deinen lokalen Port und umgehe den Tunnel:

curl -s http://127.0.0.1:3000/debug \ -H ‘X-Forwarded-For: 203.0.113.9’ \ -H ‘X-Forwarded-Proto: https’ \ -H ‘X-Forwarded-Host: evil.example’ “`

Eine korrekte Konfiguration meldet die Socket-Adresse als Client, unverschlüsseltes HTTP und deinen echten Host, weil die Verbindungsadresse kein vertrauenswürdiger Proxy war. Fordere dann dieselbe Route durch den Tunnel mit einem gefälschten X-Forwarded-For an und bestätige, dass deine App die edge-hinzugefügte Adresse meldet, nicht die gefälschte. Führe beide Checks in jeder Umgebung aus, da Staging oft eine Produktionskonfiguration erbt, die für einen anderen Proxy geschrieben wurde.

Edge sinnvoll mit Traffic Policies einsetzen

Anwendungseinstellungen sind deine letzte Verteidigungslinie. Das Edge sieht die echte TCP-Verbindung, was bedeutet, dass Regeln dort nicht davon abhängen, einem Header zu vertrauen. Traffic Policies gehören vor deine App, um drei Aufgaben zu erfüllen:

  • Header-Regeln. Überschreibe oder entferne clientenseitig gelieferte X-Forwarded-*-Header, damit die App nur Werte sieht, die vom Edge gesetzt wurden.
  • IP-Regeln. Erlaube oder blockiere Besucher anhand ihrer echten Verbindungsadresse, damit eine Allowlist nicht durch einen gefälschten Header umgangen werden kann.
  • Rate-Limits basierend auf der IP. Begrenze jeden Besucher separat, damit ein lauter Client das Kontingent nicht für alle erschöpft – genau das passiert, wenn deine App auf die Adresse des Agenten setzt.

Edge-Regeln und Framework-Einstellungen unterstützen sich gegenseitig. Wenn jemals eine fehlerhafte trustProxy-Einstellung durchrutscht, hat das Edge bereits die Header normalisiert und Grenzwerte auf die echte Adresse durchgesetzt.

FAQ

Ist X-Forwarded-For sicher für Ratenbegrenzung? Nur die Einträge, die von Proxies hinzugefügt werden, denen du vertraust. Lies den Header von rechts, überspringe vertrauenswürdige Proxys und behandle den linken Wert als vom Besucher kontrolliert.

Warum bekomme ich eine Redirect-Schleife nur durch den Tunnel? Deine App sieht unverschlüsseltes HTTP, weil TLS am Edge endet. Konfiguriere dein Framework so, dass es das weitergeleitete Scheme aus einem Header zuverlässig liest.

Sollte ich trust proxy: true verwenden? Nicht hinter einem Tunnel, der Header anhängt. Vertraue der Adresse des Agenten.

Sind numerische Vertrauenswerte sicher? In Fastify waren sie es nicht, bis Version 5.12.1 sie deaktivierte. Bevorzuge überall explizite Adressen.

Bezieht sich das auf nur die lokale Entwicklung? Nein. Dasselbe Vertrauensmodell gilt auch in der Produktion hinter jedem Proxy oder Load Balancer.

Quellen

Continue from this article into the most relevant product guides and workflows.

Related Topics

#x-forwarded-for#x-forwarded-proto#x-forwarded-host#forwarded headers#forwarded header security#trust proxy#trustProxy#trust proxy settings#trust proxy Express#trust proxy Fastify#Fastify trustProxy#Django SECURE_PROXY_SSL_HEADER#Rails trusted proxies#Express behind proxy#header spoofing#IP spoofing#client IP spoofing#host header spoofing#protocol spoofing#X-Forwarded-For spoofing#CVE-2026-3635#CVE-2026-16732#Fastify CVE#Fastify vulnerability#proxy-addr vulnerability#proxy-addr#HTTPS enforcement bypass#secure cookie bypass#secure cookies behind proxy#redirect loop HTTPS#infinite redirect loop#wrong protocol detection#req.ip behind proxy#real client IP#get client IP behind proxy#rate limiting by IP#rate limiter tunnel IP#IP allowlist#IP-based access control#tunnel security#localhost tunnel#localhost tunneling#ngrok alternative#reverse proxy security#reverse proxy headers#proxy headers#web application security#application security#AppSec#secure web development#DevSecOps#DevOps security#Node.js security#Python Django security#Ruby on Rails security#developer infrastructure#cloud-native security#traffic policies#header rules#webhook testing

Keep building with InstaTunnel

Read the docs for implementation details or compare plans before you ship.

Share this article

More InstaTunnel Insights

Discover more tutorials, tips, and updates to help you build better with localhost tunneling.

Browse All Articles