-
Notifications
You must be signed in to change notification settings - Fork 455
Expand file tree
/
Copy pathurl-prefilled-privileged-action.regressions.test.ts
More file actions
61 lines (54 loc) · 3.06 KB
/
Copy pathurl-prefilled-privileged-action.regressions.test.ts
File metadata and controls
61 lines (54 loc) · 3.06 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
import { describe, expect, it } from "vite-plus/test";
import { runScanRule } from "../../../test-utils/run-scan-rule.js";
import { urlPrefilledPrivilegedAction } from "./url-prefilled-privileged-action.js";
describe("security-scan/url-prefilled-privileged-action — regressions", () => {
it("stays silent when searchParams merely coexists with next/* imports and user words", () => {
const findings = runScanRule(urlPrefilledPrivilegedAction, {
relativePath: "src/app/bookings/page.tsx",
content: `import { useSearchParams } from "next/navigation";\nimport { useUser } from "@/hooks/use-user";\n\nexport default function Page({ searchParams }: PageProps) {\n return buildMetadata(searchParams);\n}\n`,
});
expect(findings).toHaveLength(0);
});
it("flags reading a privileged role parameter from the URL", () => {
const findings = runScanRule(urlPrefilledPrivilegedAction, {
relativePath: "src/app/invite/page.tsx",
content: `const searchParams = useSearchParams();\nconst invitedRole = searchParams.get("role");\n`,
});
expect(findings).toHaveLength(1);
});
it("flags a privileged property read off Next.js searchParams", () => {
const findings = runScanRule(urlPrefilledPrivilegedAction, {
relativePath: "src/app/team/page.tsx",
content: `export default function Page({ searchParams }: PageProps) {\n prefillInvite(searchParams.userstoinvite);\n return null;\n}\n`,
});
expect(findings).toHaveLength(1);
});
it("stays silent when the read is wrapped in a validating helper (posthog getRelativeNextPath shape)", () => {
const findings = runScanRule(urlPrefilledPrivilegedAction, {
relativePath: "src/scenes/organization/confirmOrganizationLogic.ts",
content: `const nextUrl = getRelativeNextPath(new URLSearchParams(location.search).get('next'), location);\n`,
});
expect(findings).toHaveLength(0);
});
it("stays silent when a member-access read is wrapped in an infix-named validator (resolveSafe…)", () => {
const findings = runScanRule(urlPrefilledPrivilegedAction, {
relativePath: "src/app/login/page.tsx",
content: `url.searchParams.set("callbackURL",\n resolveSafeAuthCallbackURL(url.searchParams.get("callbackURL")));\n`,
});
expect(findings).toHaveLength(0);
});
it("stays silent when an aliased sanitiz*-named validator wraps a member-access read", () => {
const findings = runScanRule(urlPrefilledPrivilegedAction, {
relativePath: "src/app/login/page.tsx",
content: `import { resolveSafeAuthCallbackURL as sanitizeAuthCallbackURL } from "~/lib/auth-callback";\nconst safe = sanitizeAuthCallbackURL(url.searchParams.get("callbackURL"));\n`,
});
expect(findings).toHaveLength(0);
});
it("still flags an unvalidated callbackUrl read passed through a non-validating call", () => {
const findings = runScanRule(urlPrefilledPrivilegedAction, {
relativePath: "src/app/login/page.tsx",
content: `const callback = decodeURIComponent(url.searchParams.get("callbackUrl"));\n`,
});
expect(findings).toHaveLength(1);
});
});