UNPKG

@beignet/core

Version:

Core framework primitives for Beignet

180 lines 6.13 kB
/** * Security hooks for @beignet/core/server */ import type { HttpContractConfig } from "../../contracts/index.js"; import { type TrustedProxyConfig } from "../trusted-proxy.js"; import type { HttpRequestLike, HttpResponseHeaders, ServerHook } from "../types.js"; /** * Strict-Transport-Security configuration. * * HSTS is disabled by default because it should only be sent by HTTPS * deployments that intentionally commit browsers to the configured host policy. */ export interface StrictTransportSecurityOptions { /** * HSTS max-age value in seconds. * * Defaults to one year when `strictTransportSecurity` is configured as an * object. */ maxAgeSec?: number; /** * Include subdomains in the HSTS policy. */ includeSubDomains?: boolean; /** * Mark the policy as eligible for browser preload lists. */ preload?: boolean; } /** * Response security headers applied by `createSecurityHeadersHooks(...)`. * * Headers are only added when the response does not already define the same * header name. Route handlers can therefore opt into route-specific CSP or * download headers without fighting the global hook. */ export interface SecurityHeadersOptions { /** * Content Security Policy value. Disabled by default because browser apps need * an app-owned asset, image, frame, and script policy. */ contentSecurityPolicy?: string | false; /** * Cross-Origin-Opener-Policy value. * * Defaults to `"same-origin"`. */ crossOriginOpenerPolicy?: string | false; /** * Cross-Origin-Resource-Policy value. * * Defaults to `"same-origin"`. */ crossOriginResourcePolicy?: string | false; /** * Permissions-Policy value. * * Defaults to disabling camera, microphone, and geolocation. */ permissionsPolicy?: string | false; /** * Referrer-Policy value. * * Defaults to `"strict-origin-when-cross-origin"`. */ referrerPolicy?: string | false; /** * Strict-Transport-Security value. Pass a string for full control or an object * for Beignet to format the header. Disabled by default. */ strictTransportSecurity?: StrictTransportSecurityOptions | string | false; /** * X-Content-Type-Options value. * * Defaults to `"nosniff"`. */ xContentTypeOptions?: "nosniff" | false; /** * X-Frame-Options value. * * Defaults to `"DENY"`. Use `contentSecurityPolicy` with `frame-ancestors` * for more precise frame control. */ xFrameOptions?: "DENY" | "SAMEORIGIN" | false; } export type CsrfFailureReason = "missing_origin" | "untrusted_origin" | "missing_token" | "invalid_token"; /** * Double-submit cookie token configuration for `createCsrfHooks(...)`. */ export interface CsrfTokenOptions { /** * Header that must carry the CSRF token. * * Defaults to `"x-csrf-token"`. */ headerName?: string; /** * Cookie that stores the expected CSRF token. * * Defaults to `"beignet.csrf"`. */ cookieName?: string; } /** * Options for `createCsrfHooks(...)`. */ export interface CsrfHooksOptions { /** * Unsafe HTTP methods protected by the hook. * * Defaults to `POST`, `PUT`, `PATCH`, and `DELETE`. */ protectedMethods?: readonly string[]; /** * Additional trusted origins allowed to send protected requests. * * The request URL's own origin is always trusted. Use this for sibling * frontends such as `https://app.example.com` calling `https://api.example.com`. */ trustedOrigins?: readonly string[] | ((args: { origin: string; req: HttpRequestLike; contract: HttpContractConfig; }) => boolean); /** * Whether unsafe requests without `Origin` or `Referer` are allowed. * * Defaults to `true` so server-to-server calls, tests, and older same-origin * clients keep working. Set to `false` for cookie-backed browser-only APIs. */ allowMissingOrigin?: boolean; /** * Optional double-submit cookie token check. * * When configured, protected requests must send the same token in the * configured header and cookie. */ token?: false | CsrfTokenOptions; /** * Hook-local trusted-proxy policy used when comparing the request's external * origin against `Origin` or `Referer`. This overrides the server-level * policy. * * Configure this only when the app is always behind a platform or reverse * proxy that strips or normalizes forwarding headers. Without this option, * CSRF uses the `requestInfo` resolved by `createServer(...)`. */ trustedProxy?: TrustedProxyConfig; /** * App-owned escape hatch for routes that have another verifier, such as * provider webhooks or auth callbacks. */ skip?: (args: { req: HttpRequestLike; contract: HttpContractConfig; params: Record<string, string>; }) => boolean | Promise<boolean>; } /** * Apply Beignet's default security response headers to a mutable header record. * * Existing headers are preserved case-insensitively so route-owned responses can * provide more specific policies. */ export declare function applySecurityHeaders(headers: HttpResponseHeaders, options?: SecurityHeadersOptions): void; /** * Create a server hook that adds common browser security headers to every * response, including native streamed responses. */ export declare function createSecurityHeadersHooks<Ctx>(options?: SecurityHeadersOptions): ServerHook<Ctx>; /** * Create CSRF protection for unsafe HTTP methods. * * The default protects cookie-backed browser routes from cross-origin unsafe * requests while still allowing server-to-server calls and tests that do not * send browser origin headers. Set `allowMissingOrigin: false` and configure * `token` for stricter browser-only APIs. */ export declare function createCsrfHooks<Ctx>(options?: CsrfHooksOptions): ServerHook<Ctx>; //# sourceMappingURL=security.d.ts.map