Docker-Images bauen und veroeffentlichen / build-and-push (push) Canceled after 0s
Traefik vertraut seit 2026-10-12 den weitergeleiteten Headern aus Cloudflare-Netzen. Wer eine eigene Cloudflare-Zone auf den Server zeigen laesst, konnte damit X-Real-IP und den ersten X-Forwarded-For-Eintrag faelschen und die Rate-Limits (Buchung, Kontakt, Login, 2FA) umgehen. - clientIp: Gegenstelle ist der letzte X-Forwarded-For-Eintrag (von Traefik angehaengt); CF-Connecting-IP nur, wenn sie eine Cloudflare-Edge ist. - better-auth liest nur noch x-artista-client-ip, den der Auth-Endpunkt per withClientIp setzt (ein mitgeschickter Wert wird ersetzt). Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
32 lines
1.6 KiB
TypeScript
32 lines
1.6 KiB
TypeScript
import { describe, expect, test } from "vitest";
|
|
import { CLIENT_IP_HEADER, clientIp, withClientIp } from "@/lib/rate-limit";
|
|
|
|
const h = (values: Record<string, string>) => new Headers(values);
|
|
|
|
describe("clientIp hinter Traefik", () => {
|
|
test("Gegenstelle ist der letzte Eintrag in X-Forwarded-For, nie ein Eintrag des Clients", () => {
|
|
expect(clientIp(h({ "x-forwarded-for": "1.2.3.4, 198.51.100.9", "x-real-ip": "1.2.3.4" }))).toBe("198.51.100.9");
|
|
});
|
|
|
|
test("über Cloudflare gefälschtes X-Real-IP zählt nicht, CF-Connecting-IP nur von Cloudflare-Edges", () => {
|
|
const viaCloudflare = { "x-real-ip": "1.2.3.4", "x-forwarded-for": "1.2.3.4, 203.0.113.7, 172.70.1.2", "cf-connecting-ip": "203.0.113.7" };
|
|
expect(clientIp(h(viaCloudflare))).toBe("203.0.113.7");
|
|
expect(clientIp(h({ "x-forwarded-for": "198.51.100.9", "cf-connecting-ip": "203.0.113.7" }))).toBe("198.51.100.9");
|
|
});
|
|
|
|
test("ohne X-Forwarded-For (lokal) gilt X-Real-IP, ungültige Werte ergeben „unknown“", () => {
|
|
expect(clientIp(h({ "x-real-ip": "198.51.100.9" }))).toBe("198.51.100.9");
|
|
expect(clientIp(h({}))).toBe("unknown");
|
|
expect(clientIp(h({ "x-forwarded-for": "1.2.3.4, kein-ip" }))).toBe("unknown");
|
|
});
|
|
|
|
test("withClientIp setzt den Header für better-auth und überschreibt einen mitgeschickten Wert", () => {
|
|
const request = new Request("https://example.org/api/auth/sign-in/email", {
|
|
method: "POST",
|
|
headers: { "x-forwarded-for": "1.2.3.4, 198.51.100.9", [CLIENT_IP_HEADER]: "1.2.3.4" },
|
|
body: "{}",
|
|
});
|
|
expect(withClientIp(request).headers.get(CLIENT_IP_HEADER)).toBe("198.51.100.9");
|
|
});
|
|
});
|