Skip to content
Snippets Groups Projects
Commit cea741fd authored by Emmanuel Raviart's avatar Emmanuel Raviart
Browse files

Add CSRF handler that is compatible with OpenID Connect authentication

parent 11c93821
No related branches found
No related tags found
No related merge requests found
Pipeline #10009 passed
......@@ -2,12 +2,11 @@ import type { Handle } from "@sveltejs/kit"
import { sequence } from "@sveltejs/kit/hooks"
import { openIdConnectHandler } from "$lib/server/openid_connect_handler"
import { csrfHandler } from "$lib/server/csrf_handler"
import { userHandler } from "$lib/server/user_handler"
export const handle: Handle = sequence(
csrfHandler(["/auth/login_callback", "/auth/logout_callback"]),
userHandler,
openIdConnectHandler,
// async ({ event, resolve }) => {
// return await resolve(event)
// },
)
import { error, json, text, type Handle } from "@sveltejs/kit"
/**
* CSRF protection copied from sveltekit but with the ability to turn it off for specific routes.
* See https://github.com/sveltejs/kit/issues/6784#issuecomment-1416104897.
*/
export const csrfHandler =
(allowedPaths: string[]): Handle =>
async ({ event, resolve }) => {
const forbidden =
event.request.method === "POST" &&
event.request.headers.get("origin") !== event.url.origin &&
isFormContentType(event.request) &&
!allowedPaths.includes(event.url.pathname)
if (forbidden) {
const csrfError = error(
403,
`Cross-site ${event.request.method} form submissions are forbidden`,
)
if (event.request.headers.get("accept") === "application/json") {
return json(csrfError.body, { status: csrfError.status })
}
return text(csrfError.body.message, { status: csrfError.status })
}
return resolve(event)
}
function isContentType(request: Request, ...types: string[]) {
const type =
request.headers.get("content-type")?.split(";", 1)[0].trim() ?? ""
return types.includes(type)
}
function isFormContentType(request: Request) {
return isContentType(
request,
"application/x-www-form-urlencoded",
"multipart/form-data",
)
}
......@@ -4,22 +4,20 @@ import { vitePreprocess } from "@sveltejs/kit/vite"
/** @type {import('@sveltejs/kit').Config} */
const config = {
kit: {
// By default, `npm run build` will create a standard Node app.
// You can create optimized builds for different platforms by
// specifying a different adapter
adapter: adapter({
precompress: true,
}),
csrf: {
// Disabling is required for authentication.
// But CSRF check is done by csrfHandler.
checkOrigin: false,
},
},
// Consult https://kit.svelte.dev/docs/integrations#preprocessors
// for more information about preprocessors
preprocess: vitePreprocess(),
preprocess: [vitePreprocess({})],
}
export default config
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment