Verificarea de redirect care are încredere în slash-ul de la început
TypeScript · Redirect-ul de după login într-un API Express · Securitate · dificultate 1/3 · ~5 min
După un login reușit, API-ul îl trimite pe utilizator înapoi la pagina pe care o ceruse inițial. Destinația vine dintr-un parametru de query ?next=, deci e controlată de utilizator. Un coleg i-a cerut asistentului AI: „Scrie resolveRedirect(target, fallback) pentru endpoint-ul nostru de login. Permite redirect doar spre pagini de pe site-ul nostru; orice altceva trebuie să meargă la fallback.”
Codul a venit cu teste care trec. Contractul promis de docstring:
resolveRedirect(target, fallback)returneazătargetcând e o cale locală de pe acest site șifallbackîn rest.- Un
targetlipsă, gol sau format doar din whitespace duce la fallback. - URL-urile absolute spre alte hosturi (
https://evil.example) nu trebuie returnate niciodată. isLocalPath(url)este predicatul din spate:truedoar pentru căile pe care browserul le va rezolva pe originea curentă.
Ține minte cum interpretează un browser un header Location: nu caută doar http://. Fă review codului înainte să ajungă în producție.
Repară codul până trec testele ascunse.
code.ts
Teste vizibile (trec pe codul primit)
import { describe, it, expect } from "@debunk/harness";
import { resolveRedirect, isLocalPath } from "./code";
describe("resolveRedirect", () => {
it("keeps a local path", () => {
expect(resolveRedirect("/settings/profile?tab=security")).toBe("/settings/profile?tab=security");
});
it("falls back for an absolute URL to another host", () => {
expect(resolveRedirect("https://evil.example/login")).toBe("/dashboard");
expect(isLocalPath("http://evil.example")).toBe(false);
});
it("falls back when the target is missing", () => {
expect(resolveRedirect(null)).toBe("/dashboard");
expect(resolveRedirect(" ", "/home")).toBe("/home");
});
});