File
Blob: src/worker/security/same-origin.ts
| 1 | import { createMiddleware } from "hono/factory"; |
| 2 | |
| 3 | import type { AppEnv } from "@/worker/hono"; |
| 4 | import { HttpError } from "@/worker/http"; |
| 5 | |
| 6 | const SAFE_METHODS = new Set(["GET", "HEAD", "OPTIONS"]); |
| 7 | const TRUSTED_FETCH_SITE_VALUES = new Set(["same-origin", "none"]); |
| 8 | |
| 9 | export const requireSameOrigin = createMiddleware<AppEnv>(async (c, next) => { |
| 10 | if (SAFE_METHODS.has(c.req.method)) { |
| 11 | await next(); |
| 12 | return; |
| 13 | } |
| 14 | |
| 15 | const requestOrigin = new URL(c.req.url).origin; |
| 16 | const origin = c.req.header("origin")?.trim(); |
| 17 | |
| 18 | if (origin) { |
| 19 | if (origin !== requestOrigin) { |
| 20 | throw new HttpError(403, "cross_origin_blocked", "Cross-origin request blocked."); |
| 21 | } |
| 22 | |
| 23 | await next(); |
| 24 | return; |
| 25 | } |
| 26 | |
| 27 | const fetchSite = c.req.header("sec-fetch-site")?.trim().toLowerCase(); |
| 28 | if (fetchSite && TRUSTED_FETCH_SITE_VALUES.has(fetchSite)) { |
| 29 | await next(); |
| 30 | return; |
| 31 | } |
| 32 | |
| 33 | throw new HttpError(403, "cross_origin_blocked", "Cross-origin request blocked."); |
| 34 | }); |