agentfootprint
Version:
The explainable agent framework — backtrack a wrong answer to the exact context that caused it (evidence, not guesses). Built on footprintjs.
35 lines (34 loc) • 1.88 kB
TypeScript
/**
* hosting/signin/returnTo — where a sign-in sends the browser afterwards, and
* why it can never be off the public origin (design §5.5; RFC 9700 §4.11.1:
* "Clients MUST NOT expose open redirectors").
*
* Written down so nobody improvises "starts with `/`", which passes
* `//evil.example`, `/\evil.example` (browsers read `\` as `/`) and
* `/<TAB>/evil.example` (the URL parser drops tab, CR and LF):
*
* 1. Only a relative path: exactly one leading `/`; no `\` and no control
* character anywhere in the raw input; never an absolute URL, even one
* naming our own origin.
* 2. Resolved against the public URL anyway, and refused unless the result's
* origin IS the public origin — a second check for a parser quirk step 1
* missed.
* 3. Only the re-serialised `pathname + search + hash` is kept: that string,
* not the input, is what gets sealed and redirected to. It must still
* start with exactly one `/`: dot segments (`/.//evil.example`,
* `/%2e%2e//evil.example`) resolve to the pathname `//evil.example`, a
* protocol-relative redirect — this check is their only guard.
* 4. The KEPT form is at most 512 bytes (review idI57 S-2): it rides in a
* sealed cookie, and percent-encoding can grow 900 raw characters to
* 5 KB, past a browser's per-cookie cap.
* 5. Never the door itself (`/auth/login` would loop through a silent-SSO
* IdP, minting a sign-in per lap — review idI57 N-3).
* 6. Anything refused becomes `/`.
*/
/** The longest kept `returnTo`, in bytes after encoding. */
export declare const MAX_RETURN_TO_BYTES = 512;
/**
* The safe place to send the browser: a same-origin path, or `/`.
* `doorPrefix` (the sign-in door's, `/auth`): a path under it becomes `/`.
*/
export declare function safeReturnTo(input: unknown, publicUrl: URL, doorPrefix?: string): string;