mirror of
https://github.com/mealie-recipes/mealie.git
synced 2026-07-18 21:50:16 -04:00
fix: preserve deep link when redirecting to login (#7876)
This commit is contained in:
27
frontend/app/lib/validators/redirect.test.ts
Normal file
27
frontend/app/lib/validators/redirect.test.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import { describe, expect, test } from "vitest";
|
||||
import { isSafeRedirectTarget } from "./redirect";
|
||||
|
||||
describe("isSafeRedirectTarget", () => {
|
||||
test("accepts an internal path", () => {
|
||||
expect(isSafeRedirectTarget("/g/home/r/some-recipe")).toBe(true);
|
||||
});
|
||||
|
||||
test("rejects protocol-relative URLs", () => {
|
||||
expect(isSafeRedirectTarget("//evil.com")).toBe(false);
|
||||
});
|
||||
|
||||
test("rejects backslash variants used to bypass same-origin checks", () => {
|
||||
expect(isSafeRedirectTarget("/\\evil.com")).toBe(false);
|
||||
expect(isSafeRedirectTarget("\\\\evil.com")).toBe(false);
|
||||
});
|
||||
|
||||
test("rejects absolute URLs", () => {
|
||||
expect(isSafeRedirectTarget("https://evil.com")).toBe(false);
|
||||
});
|
||||
|
||||
test("rejects empty or missing values", () => {
|
||||
expect(isSafeRedirectTarget("")).toBe(false);
|
||||
expect(isSafeRedirectTarget(null)).toBe(false);
|
||||
expect(isSafeRedirectTarget(undefined)).toBe(false);
|
||||
});
|
||||
});
|
||||
4
frontend/app/lib/validators/redirect.ts
Normal file
4
frontend/app/lib/validators/redirect.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
// rejects protocol-relative payloads (`//evil.com`, `/\evil.com`) that a bare startsWith("/") check would miss
|
||||
export function isSafeRedirectTarget(target: string | null | undefined): target is string {
|
||||
return !!target && target.startsWith("/") && !/^[/\\]{2}/.test(target);
|
||||
}
|
||||
Reference in New Issue
Block a user