Skip to content
Closed
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
"start": "next start",
"lint": "eslint",
"test": "vitest run",
"coverage": "vitest run src/components/project-trace-readiness.test.ts --coverage --coverage.provider=v8 --coverage.reporter=json-summary --coverage.reporter=json --coverage.include=src/components/project-trace-readiness.ts",
"coverage": "vitest run --coverage --coverage.provider=v8 --coverage.reporter=json-summary --coverage.reporter=json",
"coverage:trace-readiness": "vitest run src/components/project-trace-readiness.test.ts --coverage --coverage.provider=v8 --coverage.reporter=json-summary --coverage.reporter=json --coverage.include=src/components/project-trace-readiness.ts",
"typecheck": "tsc --noEmit",
"full:smoke": "node scripts/full-product-ui-smoke.mjs",
"pilot:smoke": "node scripts/pilot-ui-smoke.mjs",
Expand Down
5 changes: 2 additions & 3 deletions frontend/src/app/api/[...path]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -278,9 +278,8 @@ async function proxyApiRequest(

let response: Response;
try {
// `target` is rebuilt by trustedBackendOrigin() from operator-only runtime
// configuration, then constrained to the validated API path/query above.
// codeql[js/request-forgery]
// `target` is rebuilt from URI-encoded authority/path components and the
// allow-listed query parameters above.
response = await fetch(target, init);
} catch (error) {
// If the backend isn't available (e.g. during build), return a 503 instead of throwing
Expand Down
5 changes: 3 additions & 2 deletions frontend/src/lib/backend-url.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,10 @@ export function trustedBackendOrigin(): URL {
if (configured.protocol !== "https:") {
throw new Error("Backend requests require HTTPS");
}
const escapedHostname = encodeURIComponent(hostname);
const encodedHostname = hostname.includes(":")
? `[${hostname}]`
: encodeURIComponent(hostname);
? `[${escapedHostname.replaceAll("%3A", ":")}]`
: escapedHostname;
const encodedPort = configured.port
? `:${encodeURIComponent(configured.port)}`
: "";
Expand Down
Loading