address review: reject wildcard input, use shared stringCompare

Co-Authored-By: mantra <mantra@stack-auth.com>
This commit is contained in:
Devin AI 2026-06-16 21:35:19 +00:00
parent 5e12e98884
commit a363072c0e
2 changed files with 13 additions and 12 deletions

View File

@ -31,4 +31,9 @@ describe("clickmap origin options", () => {
expect(normalizeClickmapOrigin("https://app.dev.stack-auth.com/dashboard")).toMatchInlineSnapshot(`"https://app.dev.stack-auth.com"`);
expect(normalizeClickmapOrigin("javascript:alert(1)")).toMatchInlineSnapshot(`null`);
});
it("rejects wildcard origins to prevent percent-encoded URLs", () => {
expect(normalizeClickmapOrigin("https://**.example.com")).toMatchInlineSnapshot(`null`);
expect(normalizeClickmapOrigin("https://*.stack-auth.com")).toMatchInlineSnapshot(`null`);
});
});

View File

@ -1,3 +1,5 @@
import { stringCompare } from "@hexclave/shared/dist/utils/strings";
export type ClickmapOrigin = {
id: string,
origin: string,
@ -9,6 +11,10 @@ export type ClickmapWildcardDomain = {
};
export function normalizeClickmapOrigin(baseUrl: string): string | null {
if (baseUrl.includes("*")) {
return null;
}
let url: URL;
try {
url = new URL(baseUrl);
@ -27,16 +33,6 @@ function isWildcardDomain(baseUrl: string): boolean {
return baseUrl.includes("*");
}
function compareStrings(a: string, b: string): number {
if (a < b) {
return -1;
}
if (a > b) {
return 1;
}
return 0;
}
export function getClickmapOriginOptions(trustedDomains: Record<string, { baseUrl?: string | null }>): {
origins: ClickmapOrigin[],
wildcardDomains: ClickmapWildcardDomain[],
@ -63,7 +59,7 @@ export function getClickmapOriginOptions(trustedDomains: Record<string, { baseUr
}
return {
origins: Array.from(byOrigin.values()).sort((a, b) => compareStrings(a.origin, b.origin)),
wildcardDomains: wildcardDomains.sort((a, b) => compareStrings(a.baseUrl, b.baseUrl)),
origins: Array.from(byOrigin.values()).sort((a, b) => stringCompare(a.origin, b.origin)),
wildcardDomains: wildcardDomains.sort((a, b) => stringCompare(a.baseUrl, b.baseUrl)),
};
}