Skip to content

Arcjet Nosecone reference

npm badge

Arcjet Nosecone is an open source library that helps set security headers such as Content-Security-Policy (CSP), Strict-Transport-Security (HSTS), and X-Content-Type-Options in JS applications built with Bun, Deno, Next.js, Node.js, or SvelteKit.

What are Arcjet utilities?

Arcjet utilities are independent libraries that do not require the use of the main Arcjet SDK—they can be used with or without other Arcjet rules.

We take the pain out of implementing security tasks through these utilities to provide a security as code approach to developer-first security.

Quick start

To get started, follow our quick start guide.

Next.js security headers middleware

npm badge

Next.js security headers can be set using the @nosecone/next adapter.

This provides defaults to ensure Next.js applications work in production & development environments and the createMiddleware(options?: NoseconeOptions) API to create a Next.js middleware that runs on every request.

If the Content-Security-Policy header is specified via middleware, Next.js will look for a script-src that starts with nonce- and apply it for each <script> generated by the framework. This requires that opting-out of static generation, which requires modifying your Layout:

Additional resources:

SvelteKit security headers configuration

npm badge

The @nosecone/sveltekit adapter provides defaults to ensure SvelteKit is configured correctly.

This also provides the csp(options?: ContentSecurityPolicyConfig) function to translate Nosecone configuration to SvelteKit configuration in svelte.config.js, and the createHook(options?: NoseconeOptions) function to create a SvelteKit hook that runs on every request.

Update your svelte.config.js to configure csp:

svelte.config.js
import adapter from "@sveltejs/adapter-auto";
import { vitePreprocess } from "@sveltejs/vite-plugin-svelte";
import { csp } from "@nosecone/sveltekit"
/** @type {import('@sveltejs/kit').Config} */
const config = {
preprocess: vitePreprocess(),
kit: {
// Apply CSP with Nosecone defaults
csp: csp(),
adapter: adapter(),
},
};
export default config;

Additional resources:

API

nosecone(options?: NoseconeOptions): Headers

The default export is a function that returns a set of Headers to apply to a request that help you secure your application. The defaults should work for many applications, but all can be configured or disabled for specific requirements.

NoseconeOptions

All entries in NoseconeOptions can be enabled with defaults by specifying true or disabled by specifying false. Additionally, many allow individual configuration via their own configuration objects, which override any defaults.

You can use object spread, e.g. ...defaults, to combine the default values with your overrides.

interface NoseconeOptions {
/**
* Configure the `Content-Security-Policy` header, which helps mitigate a
* large number of attacks, such as cross-site scripting.
*/
contentSecurityPolicy?: ContentSecurityPolicyConfig | boolean;
/**
* Configure the `Cross-Origin-Embedder-Policy` header, which helps control
* what resources can be loaded cross-origin.
*/
crossOriginEmbedderPolicy?: CrossOriginEmbedderPolicyConfig | boolean;
/**
* Configure the `Cross-Origin-Opener-Policy` header, which helps
* process-isolate your page.
*/
crossOriginOpenerPolicy?: CrossOriginOpenerPolicyConfig | boolean;
/**
* Configure the `Cross-Origin-Resource-Policy` header, which blocks others
* from loading your resources cross-origin in some cases.
*/
crossOriginResourcePolicy?: CrossOriginResourcePolicyConfig | boolean;
/**
* Configure the `Origin-Agent-Cluster` header, which provides a mechanism to
* allow web applications to isolate their origins from other processes.
*/
originAgentCluster?: boolean;
/**
* Configure the `Referrer-Policy` header, which controls what information is
* set in the `Referer` request header.
*/
referrerPolicy?: ReferrerPolicyConfig | boolean;
/**
* Configure the `Strict-Transport-Security` header, which tells browsers to
* prefer HTTPS instead of insecure HTTP.
*/
strictTransportSecurity?: StrictTransportSecurityConfig | boolean;
/**
* Configure the `X-Content-Type-Options` header, which helps mitigate MIME
* type sniffing that can cause security issues.
*/
xContentTypeOptions?: boolean;
/**
* Configure the `X-DNS-Prefetch-Control` header, which helps control DNS
* prefetching to improve user privacy at the expense of performance.
*/
xDnsPrefetchControl?: DnsPrefetchControlConfig | boolean;
/**
* Configure the `X-Download-Options` header, which prevents a user from
* opening a file directly in Internet Explorer 8 to avoid prevent script
* injection.
*/
xDownloadOptions?: boolean;
/**
* Configure the `X-Frame-Options` header, which helps mitigate clickjacking
* attacks in legacy browsers. This header is superceded by a directive in the
* `Content-Security-Policy` header.
*/
xFrameOptions?: FrameOptionsConfig | boolean;
/**
* Configure the `X-Permitted-Cross-Domain-Policies` header, which tells some
* clients, like Adobe products, your domain's policy for loading cross-domain
* content.
*/
xPermittedCrossDomainPolicies?: PermittedCrossDomainPoliciesConfig | boolean;
/**
* Disable the `X-XSS-Protection` header, which could introduce a browser
* side-channel if enabled.
*/
xXssProtection?: boolean;
}

withVercelToolbar(options: NoseconeOptions): NoseconeOptions

Nosecone provides the withVercelToolbar utility function to augment Nosecone options so the Vercel Toolbar is allowed by the various headers.

This follows the guidelines documented by Vercel under Using a Content Security Policy, but we recommend conditionally adding this based on process.env.VERCEL_ENV:

Headers

Content-Security-Policy

The Content-Security-Policy header is a powerful allow-list of what can happen on your page which helps mitigate many attacks, such as cross-site scripting.

Types:

type StaticOrDynamic<S> = boolean | readonly (S | (() => S))[] | null;
type Source =
| `${string}.${string}`
| "localhost"
| `${string}.${string}:${number}`
| `${string}.${string}:*`
| `localhost:${number}`
| "localhost:*"
| `${string}://${string}.${string}`
| `${string}://${string}.${string}:${number}`
| `${string}://${string}.${string}:*`
| `${string}://localhost`
| `${string}://localhost:${number}`
| `${string}://localhost:*`
| "http:"
| "https:"
| "data:"
| "mediastream:"
| "blob:"
| "filesystem:"
| `'nonce-${string}'`
| `'sha256-${string}'`
| `'sha384-${string}'`
| `'sha512-${string}'`
| "'self'"
| "'unsafe-eval'"
| "'unsafe-hashes'"
| "'unsafe-inline'"
| "'wasm-unsafe-eval'"
| "'none'";
type HostSource =
| `${string}.${string}`
| "localhost"
| `${string}.${string}:${number}`
| `${string}.${string}:*`
| `localhost:${number}`
| "localhost:*"
| `${string}://${string}.${string}`
| `${string}://${string}.${string}:${number}`
| `${string}://${string}.${string}:*`
| `${string}://localhost`
| `${string}://localhost:${number}`
| `${string}://localhost:*`;
type SchemeSource =
| "http:"
| "https:"
| "data:"
| "mediastream:"
| "blob:"
| "filesystem:";
type FrameSource =
| `${string}.${string}`
| "localhost"
| `${string}.${string}:${number}`
| `${string}.${string}:*`
| `localhost:${number}`
| "localhost:*"
| `${string}://${string}.${string}`
| `${string}://${string}.${string}:${number}`
| `${string}://${string}.${string}:*`
| `${string}://localhost`
| `${string}://localhost:${number}`
| `${string}://localhost:*`
| "http:"
| "https:"
| "data:"
| "mediastream:"
| "blob:"
| "filesystem:"
| "'self'"
| "'none'";
type ActionSource = "'strict-dynamic'" | "'report-sample'";
type CspDirectives = {
baseUri?: StaticOrDynamic<Source | ActionSource> | undefined;
childSrc?: StaticOrDynamic<Source> | undefined;
defaultSrc?: StaticOrDynamic<Source | ActionSource> | undefined;
frameSrc?: StaticOrDynamic<Source> | undefined;
workerSrc?: StaticOrDynamic<Source> | undefined;
connectSrc?: StaticOrDynamic<Source> | undefined;
fontSrc?: StaticOrDynamic<Source> | undefined;
imgSrc?: StaticOrDynamic<Source> | undefined;
manifestSrc?: StaticOrDynamic<Source> | undefined;
mediaSrc?: StaticOrDynamic<Source> | undefined;
objectSrc?: StaticOrDynamic<Source> | undefined;
prefetchSrc?: StaticOrDynamic<Source> | undefined;
scriptSrc?: StaticOrDynamic<Source | ActionSource> | undefined;
scriptSrcElem?: StaticOrDynamic<Source> | undefined;
scriptSrcAttr?: StaticOrDynamic<Source> | undefined;
styleSrc?: StaticOrDynamic<Source | ActionSource> | undefined;
styleSrcElem?: StaticOrDynamic<Source> | undefined;
styleSrcAttr?: StaticOrDynamic<Source> | undefined;
sandbox?:
| ReadonlyArray<
| "allow-downloads-without-user-activation"
| "allow-forms"
| "allow-modals"
| "allow-orientation-lock"
| "allow-pointer-lock"
| "allow-popups"
| "allow-popups-to-escape-sandbox"
| "allow-presentation"
| "allow-same-origin"
| "allow-scripts"
| "allow-storage-access-by-user-activation"
| "allow-top-navigation"
| "allow-top-navigation-by-user-activation"
>
| undefined;
formAction?: StaticOrDynamic<Source | ActionSource> | undefined;
frameAncestors?:
| StaticOrDynamic<HostSource | SchemeSource | FrameSource>
| undefined;
navigateTo?: StaticOrDynamic<Source | ActionSource> | undefined;
reportUri?: string[] | undefined;
reportTo?: string[] | undefined;
requireTrustedTypesFor?: ReadonlyArray<"script"> | undefined;
trustedTypes?:
| ReadonlyArray<"none" | "allow-duplicates" | "*" | string>
| undefined;
upgradeInsecureRequests?: boolean | undefined;
};
type ContentSecurityPolicyConfig = {
directives?: Readonly<CspDirectives> | undefined;
};

Defaults:

{
directives: {
baseUri: ["'none'"],
childSrc: ["'none'"],
connectSrc: ["'self'"],
defaultSrc: ["'self'"],
fontSrc: ["'self'"],
formAction: ["'self'"],
frameAncestors: ["'none'"],
frameSrc: ["'none'"],
imgSrc: ["'self'", "blob:", "data:"],
manifestSrc: ["'self'"],
mediaSrc: ["'self'"],
objectSrc: ["'none'"],
scriptSrc: ["'self'"],
styleSrc: ["'self'"],
workerSrc: ["'self'"],
},
}

The defaults will produce the following header:

Content-Security-Policy: base-uri 'none'; child-src 'none'; connect-src 'self'; default-src 'self'; font-src 'self'; form-action 'self'; frame-ancestors 'none'; frame-src 'none'; img-src 'self' blob: data:; manifest-src 'self'; media-src 'self'; object-src 'none'; script-src 'self'; style-src 'self'; worker-src 'self';

Additional resources:

Cross-Origin-Embedder-Policy

The Cross-Origin-Embedder-Policy header helps control what resources can be loaded cross-origin.

Types:

type CrossOriginEmbedderPolicyConfig = {
policy?: "require-corp" | "credentialless" | "unsafe-none" | undefined;
};

Defaults:

{
policy: "require-corp",
}

The defaults will produce the following header:

Cross-Origin-Embedder-Policy: require-corp

Additional resources:

Cross-Origin-Opener-Policy

The Cross-Origin-Opener-Policy header helps process-isolate your page.

Types:

type CrossOriginOpenerPolicyConfig = {
policy?:
| "same-origin"
| "same-origin-allow-popups"
| "unsafe-none"
| undefined;
};

Defaults:

{
policy: "same-origin",
}

The defaults will produce the following header:

Cross-Origin-Opener-Policy: same-origin

Additional resources:

Cross-Origin-Resource-Policy

The Cross-Origin-Resource-Policy header blocks others from loading your resources cross-origin in some cases.

Types:

type CrossOriginResourcePolicyConfig = {
policy?: "same-origin" | "same-site" | "cross-origin" | undefined;
};

Defaults:

{
policy: "same-origin",
}

The defaults will produce the following header:

Cross-Origin-Resource-Policy: same-origin

Additional resources:

Origin-Agent-Cluster

The Origin-Agent-Cluster header provides a mechanism to allow web applications to isolate their origins from other processes.

Types:

type OriginAgentClusterConfig = boolean;

Defaults:

true;

The defaults will produce the following header:

Origin-Agent-Cluster: ?1

Additional resources:

Referrer-Policy

The Referrer-Policy header controls what information is set in the Referer request header.

Types:

type ReferrerPolicyConfig = {
policy?: ReadonlyArray<ReferrerPolicyToken> | undefined;
};
type ReferrerPolicyToken =
| ""
| "no-referrer"
| "no-referrer-when-downgrade"
| "same-origin"
| "origin"
| "strict-origin"
| "origin-when-cross-origin"
| "strict-origin-when-cross-origin"
| "unsafe-url";

Defaults:

{
policy: ["no-referrer"],
}

The defaults will produce the following header:

Referrer-Policy: no-referrer

Additional resources:

Strict-Transport-Security

The Strict-Transport-Security header tells browsers to prefer HTTPS instead of insecure HTTP.

Types:

type StrictTransportSecurityConfig = {
maxAge?: number | undefined;
includeSubDomains?: boolean | undefined;
preload?: boolean | undefined;
};

Defaults:

{
maxAge: 31536000, // 1 year
includeSubDomains: true,
preload: false,
}

The defaults will produce the following header:

Strict-Transport-Security: max-age=31536000; includeSubDomains

Additional resources:

X-Content-Type-Options

The X-Content-Type-Options header helps mitigate MIME type sniffing that can cause security issues.

Types:

type ContentTypeOptionsConfig = boolean;

Defaults:

true;

The defaults will produce the following header:

X-Content-Type-Options: nosniff

Additional resources:

X-DNS-Prefetch-Control

The X-DNS-Prefetch-Control header helps control DNS prefetching to improve user privacy at the expense of performance.

Types:

type DnsPrefetchControlConfig = {
allow?: boolean | undefined;
};

Defaults:

{
allow: false,
}

The defaults will produce the following header:

X-DNS-Prefetch-Control: off

Additional resources:

X-Download-Options (legacy)

The legacy X-Download-Options header prevented a user from opening a file directly in Internet Explorer to avoid prevent script injection.

Types:

type DownloadOptionsCofig = boolean;

Defaults:

true;

The defaults will produce the following header:

X-Download-Options: noopen

Additional resources:

X-Frame-Options (legacy)

The legacy X-Frame-Options header helped mitigate clickjacking attacks in older browsers.

Types:

type FrameOptionsConfig = {
action?: "deny" | "sameorigin" | undefined;
};

Defaults:

{
action: "sameorigin",
}

The defaults will produce the following header:

X-Frame-Options: SAMEORIGIN

Additional resources:

X-Permitted-Cross-Domain-Policies

The X-Permitted-Cross-Domain-Policies header tells some clients, like Adobe products, your domain’s policy for loading cross-domain content.

Types:

type PermittedCrossDomainPoliciesConfig = {
permittedPolicies?:
| "none"
| "master-only"
| "by-content-type"
| "all"
| undefined;
};

Defaults:

{
permittedPolicies: "none",
}

The defaults will produce the following header:

X-Permitted-Cross-Domain-Policies: none

Additional resources:

X-XSS-Protection (legacy)

The legacy X-XSS-Protection header tried to mitigate XSS attacks, but accidentally enabled side-channel attacks in older browsers, so Nosecone disables it.

Types:

type XssProtectionConfig = boolean;

Defaults:

true;

The defaults will produce the following header:

X-XSS-Protection: 0

Additional resources: