fix(console): secure server action redirects (#45374)

This commit is contained in:
Adam
2026-08-26 15:03:16 -05:00
committed by GitHub
parent c5ef753d28
commit c2eacd72af
3 changed files with 48 additions and 0 deletions
@@ -0,0 +1,11 @@
export function sanitizeServerActionRequest(request: Request) {
const requestUrl = new URL(request.url)
if (requestUrl.pathname !== "/_server") return request
const referer = request.headers.get("referer")
if (referer && URL.canParse(referer) && new URL(referer).origin === requestUrl.origin) return request
const sanitized = new Request(request)
sanitized.headers.set("referer", requestUrl.origin)
return sanitized
}
+3
View File
@@ -1,9 +1,12 @@
import { createMiddleware } from "@solidjs/start/middleware"
import { LOCALE_HEADER, cookie, fromPathname, strip } from "~/lib/language"
import { normalizeReferralCode, referralCookie } from "~/lib/referral-invite"
import { sanitizeServerActionRequest } from "~/lib/server-action"
export default createMiddleware({
onRequest(event) {
event.request = sanitizeServerActionRequest(event.request)
const url = new URL(event.request.url)
const locale = fromPathname(url.pathname)
if (locale) {
@@ -0,0 +1,34 @@
import { describe, expect, test } from "bun:test"
import { sanitizeServerActionRequest } from "../src/lib/server-action"
describe("server action referer", () => {
test("preserves same-origin return locations", () => {
const request = new Request("https://dev.opencode.ai/_server?id=action", {
headers: { referer: "https://dev.opencode.ai/auth?next=%2Fconsole" },
})
expect(sanitizeServerActionRequest(request)).toBe(request)
})
test("replaces unsafe return locations with the request origin", () => {
const referers = ["https://evil.example/phishing-login", "not a url", undefined]
expect(
referers.map((referer) =>
sanitizeServerActionRequest(
new Request("https://dev.opencode.ai/_server?id=action", {
headers: referer === undefined ? undefined : { referer },
}),
).headers.get("referer"),
),
).toEqual(["https://dev.opencode.ai", "https://dev.opencode.ai", "https://dev.opencode.ai"])
})
test("does not change other routes", () => {
const request = new Request("https://dev.opencode.ai/auth", {
headers: { referer: "https://evil.example/phishing-login" },
})
expect(sanitizeServerActionRequest(request)).toBe(request)
})
})