Docs/Runtime & Infrastructure/Security

Runtime & Infrastructure

Security

Security — Runtime & Infrastructure documentation for BCP Framework.

Last updated: 2026-08-30T23:15:12

Security

BCP Framework applies a security gateway in both development and standalone production modes and exposes server-side mutation protection primitives through bcp/server.

Default response headers

The default policy includes:

http
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: camera=(), microphone=(), geolocation=()

X-Powered-By is hidden by default.

Content Security Policy

CSP is configurable but disabled by default:

TypeScript
security: {
    contentSecurityPolicy:
        "default-src 'self'; script-src 'self' 'unsafe-inline'",
}

The current client bootstrap still uses inline script content in some runtime paths, so enabling a strict CSP without a compatible nonce/hash policy can block hydration or development tooling. Nonce/hash support is a future hardening area.

Request body limit

The default request body limit is 1 MiB:

TypeScript
server: {
    bodyLimit: 1024 * 1024,
}

Requests exceeding the limit are rejected by the outer gateway with HTTP 413 before reaching the API handler.

Same-origin mutation protection — 0.2.6+

Cookie-authenticated unsafe requests can validate their browser origin:

TypeScript
import {
    requireSameOriginRequest,
} from "bcp/server";

await requireSameOriginRequest();

BCP validates Origin first and falls back to Referer. GET, HEAD and OPTIONS are treated as safe methods. Unsafe methods without origin information are rejected by default.

Additional trusted origins can be configured per check with allowedOrigins.

Malformed, opaque or unsupported origins are denied instead of surfacing as server errors.

CSRF protection — 0.2.6+

BCP also exposes signed CSRF tokens:

TypeScript
import {
    createCsrfToken,
    requireCsrfRequest,
} from "bcp/server";

const token =
    await createCsrfToken();

// Render the token through a trusted application response,
// then submit it with the mutation.

await requireCsrfRequest({
    token: submittedToken,
});

Default header/cookie:

text
X-BCP-CSRF
bcp_csrf

Token signing uses BCP_CSRF_SECRET when configured and otherwise falls back to BCP_SESSION_SECRET. Secrets must contain at least 32 UTF-8 bytes.

requireCsrfRequest() combines same-origin validation and CSRF token verification for unsafe methods.

Read more: Authorization & Security v2.

Static assets

Public asset resolution decodes the URL, rejects null bytes, resolves the candidate beneath public/, resolves filesystem symlinks and verifies the final real path remains inside the public directory. This prevents path and symlink traversal from escaping the public root.

Middleware URLs

Middleware rewrites must remain same-origin. Redirects and rewrites reject non-HTTP(S) protocols and URLs containing embedded credentials.

Header validation

Security config values reject carriage return, line feed and null bytes to prevent response-header injection through framework configuration.

Deployment note

The security gateway is the outer production layer, so security headers and body limits also apply to response-cache hits, middleware responses, static assets and error responses.

Authorization, same-origin checks and CSRF validation remain request-handler/guard responsibilities and should be enforced wherever a mutation or protected operation occurs.