---
title: Content Security Policy | Advanced
description: Learn how to create a content security policy (CSP) to keep your Qwik app safe.
contributors:
  - tzdesign
  - jordanw66
  - mrhoodz
  - the-zimmermann
  - hamatoyogi
updated_at: '2023-06-25T19:43:33Z'
created_at: '2023-06-15T11:45:23Z'
---

import { LongNote } from '~/components/note/note';

# Content Security Policy

## What is CSP?

[Content Security Policy (CSP)](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) is an added layer of security that helps to detect and mitigate certain types of attacks, including Cross-Site Scripting (XSS) and data injection attacks. These attacks are used for everything from data theft, to site defacement, to malware distribution.

## Steps to integrate

These steps only work for SSR approach. If you are using the Server Side Generation approach, you don't have an up and running server, so this code will not run during the page request.

### Add a route plugin

To add the middleware plugin to your application, simply add a file named ```plugin@your-plugin-name.ts``` to the routes folder. 
This file will be loaded with every request, allowing you to add headers, modify the response, and more.

```bash  {3} /plugin@csp\.ts/ title="Add the plugin"
src/
└── routes/
    ├── plugin@csp.ts         # The plugin which runs on every request (route middleware)
    ├── contact/
    │   └── index.mdx         # https://example.com/contact
    ├── about/
    │   └── index.md          # https://example.com/about
    ├── index.mdx             # https://example.com/
    │
    └── layout.tsx            # This layout is used for all pages
```

#### Example

<LongNote title="CSP Template Defaults">
This template provides very permissive backward-compatible defaults. It is highly recommended that you customize it to better suit your specific use case. As this is an advanced topic, you should take a closer look at [MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) or [web.dev](https://web.dev/csp/) to get a better understanding of CSP. Please note that in dev mode the Vite scripts have no nonce and will report. For this reason, the example will not add csp in dev mode.
</LongNote>

```typescript title="src/routes/plugin@csp.ts"
import type { RequestHandler } from "@qwik.dev/router";
import { isDev } from "@qwik.dev/core";

export const onRequest: RequestHandler = event => {
  if (isDev) return; // Will not return CSP headers in dev mode
  const nonce = Date.now().toString(36); // Your custom nonce logic here
  event.sharedMap.set("@nonce", nonce);
  const csp = [
    `default-src 'self' 'unsafe-inline'`,
    `font-src 'self'`,
    `img-src 'self' 'unsafe-inline' data:`,
    `script-src 'self' 'unsafe-inline' https: 'nonce-${nonce}' 'strict-dynamic'`,
    `style-src 'self' 'unsafe-inline'`,
    `frame-src 'self' 'nonce-${nonce}'`,
    `object-src 'none'`,
    `base-uri 'self'`,
  ];

  event.headers.set("Content-Security-Policy", csp.join("; "));
};
```

### Custom scripts

If you have custom script tags that you need to add the nonce to, you can use the `useServerData` hook to get the nonce from the server and add it to your script tags.

```tsx {2,5} /nonce/ title="src/components/some-component.tsx"
export default component$(() => {
  const nonce = useServerData<string | undefined>("nonce");
  return (
    <div>
      <script nonce={nonce}>alert("Hello world")</script>
    </div>
  );
});
```


## Validate your CSP

There is a great tool to validate your CSP: [https://csp-evaluator.withgoogle.com/](https://csp-evaluator.withgoogle.com/)
