> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/honojs/hono/llms.txt
> Use this file to discover all available pages before exploring further.

# secureHeaders

> API reference for the Secure Headers middleware

## Import

```typescript theme={null}
import { secureHeaders, NONCE } from 'hono/secure-headers'
```

## Usage

```typescript theme={null}
const app = new Hono()

app.use(secureHeaders())

app.get('/', (c) => c.text('Hello Hono!'))
```

## Options

The `secureHeaders` middleware accepts an optional `SecureHeadersOptions` object:

<ParamField path="contentSecurityPolicy" type="ContentSecurityPolicyOptions">
  Settings for the Content-Security-Policy header. Configure directives like `defaultSrc`, `scriptSrc`, `styleSrc`, etc.
</ParamField>

<ParamField path="contentSecurityPolicyReportOnly" type="ContentSecurityPolicyOptions">
  Settings for the Content-Security-Policy-Report-Only header. Same structure as `contentSecurityPolicy` but for report-only mode.
</ParamField>

<ParamField path="crossOriginEmbedderPolicy" type="boolean | string" default={false}>
  Settings for the Cross-Origin-Embedder-Policy header. Default value: `"require-corp"`
</ParamField>

<ParamField path="crossOriginResourcePolicy" type="boolean | string" default={true}>
  Settings for the Cross-Origin-Resource-Policy header. Default value: `"same-origin"`
</ParamField>

<ParamField path="crossOriginOpenerPolicy" type="boolean | string" default={true}>
  Settings for the Cross-Origin-Opener-Policy header. Default value: `"same-origin"`
</ParamField>

<ParamField path="originAgentCluster" type="boolean | string" default={true}>
  Settings for the Origin-Agent-Cluster header. Default value: `"?1"`
</ParamField>

<ParamField path="referrerPolicy" type="boolean | string" default={true}>
  Settings for the Referrer-Policy header. Default value: `"no-referrer"`
</ParamField>

<ParamField path="reportingEndpoints" type="ReportingEndpointOptions[]">
  Settings for the Reporting-Endpoints header. Array of objects with `name` and `url` properties.
</ParamField>

<ParamField path="reportTo" type="ReportToOptions[]">
  Settings for the Report-To header. Array of objects with `group`, `max_age`, and `endpoints` properties.
</ParamField>

<ParamField path="strictTransportSecurity" type="boolean | string" default={true}>
  Settings for the Strict-Transport-Security header. Default value: `"max-age=15552000; includeSubDomains"`
</ParamField>

<ParamField path="xContentTypeOptions" type="boolean | string" default={true}>
  Settings for the X-Content-Type-Options header. Default value: `"nosniff"`
</ParamField>

<ParamField path="xDnsPrefetchControl" type="boolean | string" default={true}>
  Settings for the X-DNS-Prefetch-Control header. Default value: `"off"`
</ParamField>

<ParamField path="xDownloadOptions" type="boolean | string" default={true}>
  Settings for the X-Download-Options header. Default value: `"noopen"`
</ParamField>

<ParamField path="xFrameOptions" type="boolean | string" default={true}>
  Settings for the X-Frame-Options header. Default value: `"SAMEORIGIN"`
</ParamField>

<ParamField path="xPermittedCrossDomainPolicies" type="boolean | string" default={true}>
  Settings for the X-Permitted-Cross-Domain-Policies header. Default value: `"none"`
</ParamField>

<ParamField path="xXssProtection" type="boolean | string" default={true}>
  Settings for the X-XSS-Protection header. Default value: `"0"`
</ParamField>

<ParamField path="removePoweredBy" type="boolean" default={true}>
  Whether to remove the X-Powered-By header.
</ParamField>

<ParamField path="permissionsPolicy" type="PermissionsPolicyOptions" default={{}}>
  Settings for the Permissions-Policy header. Object mapping permission directives to their values.
</ParamField>

## Signature

```typescript theme={null}
secureHeaders(customOptions?: SecureHeadersOptions): MiddlewareHandler
```

## NONCE Helper

The `NONCE` helper generates a cryptographically secure nonce for CSP:

```typescript theme={null}
import { secureHeaders, NONCE } from 'hono/secure-headers'

app.use(secureHeaders({
  contentSecurityPolicy: {
    scriptSrc: [NONCE, 'https://allowed-cdn.com'],
  },
}))

app.get('/', (c) => {
  const nonce = c.get('secureHeadersNonce')
  return c.html(`<script nonce="${nonce}">alert('hello')</script>`)
})
```

## Examples

### Basic usage with defaults

```typescript theme={null}
const app = new Hono()

app.use(secureHeaders())
```

### Custom Content Security Policy

```typescript theme={null}
app.use(secureHeaders({
  contentSecurityPolicy: {
    defaultSrc: ["'self'"],
    scriptSrc: ["'self'", "'unsafe-inline'", 'https://cdn.example.com'],
    styleSrc: ["'self'", 'https://fonts.googleapis.com'],
    imgSrc: ["'self'", 'data:', 'https:'],
    fontSrc: ["'self'", 'https://fonts.gstatic.com'],
    connectSrc: ["'self'", 'https://api.example.com'],
  },
}))
```

### Using NONCE for scripts

```typescript theme={null}
app.use(secureHeaders({
  contentSecurityPolicy: {
    scriptSrc: [NONCE],
  },
}))

app.get('/', (c) => {
  const nonce = c.get('secureHeadersNonce')
  return c.html(`
    <html>
      <head>
        <script nonce="${nonce}">
          console.log('This script is allowed')
        </script>
      </head>
    </html>
  `)
})
```

### Custom Strict Transport Security

```typescript theme={null}
app.use(secureHeaders({
  strictTransportSecurity: 'max-age=63072000; includeSubDomains; preload',
}))
```

### Disable specific headers

```typescript theme={null}
app.use(secureHeaders({
  xFrameOptions: false,
  xXssProtection: false,
}))
```

### Permissions Policy

```typescript theme={null}
app.use(secureHeaders({
  permissionsPolicy: {
    camera: false,
    microphone: false,
    geolocation: ['self', 'https://trusted.example.com'],
    payment: true,
  },
}))
```

### Report-Only CSP

```typescript theme={null}
app.use(secureHeaders({
  contentSecurityPolicyReportOnly: {
    defaultSrc: ["'self'"],
    reportUri: '/csp-report',
  },
}))
```

### With Reporting Endpoints

```typescript theme={null}
app.use(secureHeaders({
  reportingEndpoints: [
    { name: 'csp-endpoint', url: 'https://example.com/csp-reports' },
  ],
  contentSecurityPolicy: {
    defaultSrc: ["'self'"],
    reportTo: 'csp-endpoint',
  },
}))
```

## Default Values

When called without options, `secureHeaders()` sets these headers:

* `Cross-Origin-Resource-Policy: same-origin`
* `Cross-Origin-Opener-Policy: same-origin`
* `Origin-Agent-Cluster: ?1`
* `Referrer-Policy: no-referrer`
* `Strict-Transport-Security: max-age=15552000; includeSubDomains`
* `X-Content-Type-Options: nosniff`
* `X-DNS-Prefetch-Control: off`
* `X-Download-Options: noopen`
* `X-Frame-Options: SAMEORIGIN`
* `X-Permitted-Cross-Domain-Policies: none`
* `X-XSS-Protection: 0`
* Removes `X-Powered-By` header

## CSP Directives

Available Content Security Policy directives:

* `defaultSrc`
* `baseUri`
* `childSrc`
* `connectSrc`
* `fontSrc`
* `formAction`
* `frameAncestors`
* `frameSrc`
* `imgSrc`
* `manifestSrc`
* `mediaSrc`
* `objectSrc`
* `reportTo`
* `reportUri`
* `sandbox`
* `scriptSrc`
* `scriptSrcAttr`
* `scriptSrcElem`
* `styleSrc`
* `styleSrcAttr`
* `styleSrcElem`
* `upgradeInsecureRequests`
* `workerSrc`
* `requireTrustedTypesFor`
* `trustedTypes`

## Behavior

* Sets security headers after handler execution
* Headers can be overridden by providing string values
* Headers can be disabled by setting to `false`
* CSP directives support dynamic values via callback functions
* NONCE helper generates unique nonce per request and stores in context
* Removes X-Powered-By header by default
* Supports both Content-Security-Policy and Content-Security-Policy-Report-Only
