@astroscope/csrf
v0.2.3
Published
CSRF protection with path exclusions — for webhooks, OIDC callbacks, and third-party integrations
Downloads
422
Maintainers
Readme
@astroscope/csrf
Note: This package is in active development. APIs may change between versions.
CSRF protection with path exclusions — for webhooks, OIDC callbacks, and third-party integrations.
Why?
Astro has built-in CSRF protection via security.checkOrigin, but it doesn't support excluding paths. This is needed when you allow cross-origin POST requests for:
- OIDC callbacks (Apple Sign-In, back-channel logout)
- Payment webhooks (Stripe, PayPal)
- Third-party integrations that POST to your endpoints
Installation
npm install @astroscope/csrfUsage (Integration)
The recommended approach - automatically configures middleware and disables Astro's built-in checkOrigin:
// astro.config.ts
import { defineConfig } from "astro/config";
import csrf from "@astroscope/csrf";
export default defineConfig({
integrations: [
csrf({
trustProxy: true,
exclude: [
{ prefix: "/auth/" },
{ exact: "/webhook" },
],
}),
],
});Options
Origin validation
Choose one of two modes:
Trust proxy (recommended when behind a load balancer):
csrf({ trustProxy: true })Explicit origins:
csrf({
origin: "https://example.com",
// or multiple:
origin: ["https://example.com", "https://app.example.com"],
})exclude (optional)
Paths to exclude from CSRF protection:
exclude: [
{ prefix: "/auth/" }, // path.startsWith("/auth/")
{ exact: "/webhook" }, // path === "/webhook"
{ pattern: /^\/api\/public\// } // regex.test(path)
]Or a function for complex logic:
exclude: (context) => context.url.pathname.startsWith("/public/")enabled (optional)
Disable CSRF protection (e.g., in development):
csrf({
enabled: import.meta.env.PROD,
trustProxy: true,
})Manual middleware setup
For dynamic configuration or custom middleware chains, use createCsrfMiddleware directly:
// src/middleware.ts
import { sequence } from "astro:middleware";
import { createCsrfMiddleware } from "@astroscope/csrf";
export const onRequest = sequence(
createCsrfMiddleware({
origin: () => process.env.ALLOWED_ORIGINS?.split(",") ?? [],
exclude: [{ prefix: "/auth/" }],
})
);When using manual setup, disable Astro's built-in check:
// astro.config.ts
export default defineConfig({
security: {
checkOrigin: false,
},
});How it works
- Skips non-mutating methods (GET, HEAD, OPTIONS)
- Skips excluded paths
- Compares request
Originheader against allowed origin(s) - Returns 403 if origins don't match or Origin header is missing
License
MIT
