---
url: /en/docs/security.md
description: >-
  Learn about Sveltia CMS’s security features, practices, and how to set up
  Content Security Policy (CSP) for a secure content management experience.
---

# Security

Security is a top priority for Sveltia CMS so that content can be managed with confidence. This document outlines the security features and practices of Sveltia CMS. It also provides best practices for securing your CMS installation.

## Our Approach

Sveltia CMS employs multiple layers of security measures to protect data and ensure a safe content management experience. Our security approach includes the following features and practices:

### Security Features

* **XSS protection**: HTML sanitation is performed using the [DOMPurify](https://github.com/cure53/DOMPurify) library. The unpatched [XSS vulnerability](https://github.com/advisories/GHSA-xp8g-32qh-mv28) in Decap CMS does not affect Sveltia CMS. The `sanitize_preview` [RichText field](/en/docs/fields/richtext) option defaults to `true`.
* **No proxy required**: The [local workflow](/en/docs/workflows/local) eliminates attack surfaces from compromised dependencies and unauthorized API access.
* **Secure contexts only**: HTTPS is required for all site content and CMS configuration.
* **Automatic referrer policy**: The `same-origin` policy is automatically set globally in the app. An exception is OpenStreetMap integration for the [Map field type](/en/docs/fields/map), which requires `strict-origin` to [load tiles properly](https://wiki.openstreetmap.org/wiki/Referer).
* **Link rel attributes**: All external links in the admin interface have `rel="noopener noreferrer"` to prevent tabnabbing and protect user privacy.
* **Sandboxed iframes**: All iframes in the admin interface are sandboxed with appropriate restrictions to prevent malicious content from executing harmful actions.
* **Simplified CSP**: No `unsafe-eval` or `unsafe-inline` needed in `script-src`. We provide a [CSP builder](#setting-up-content-security-policy) tool to help users generate a secure policy based on their specific configuration and deployment setup.
* **Signed commits**: GitHub commits are automatically GPG-signed and [verified](https://docs.github.com/en/authentication/managing-commit-signature-verification/about-commit-signature-verification).
* **Signed uploads**: [Media uploads to Uploadcare](/en/docs/media/uploadcare) are signed using secure API keys.

### Security Practices

* **AI-assisted coding**: Claude and GPT assistants are used to ensure secure coding practices and identify potential vulnerabilities during development.
* **Dependency security**: Constant full updates with `ncu -u && pnpm up`, manual and CI-driven [`pnpm audit`](https://pnpm.io/cli/audit), and Dependabot alerts deal with vulnerabilities quickly. `pnpm`’s `minimumReleaseAge` option [protect against supply chain attacks](https://pnpm.io/supply-chain-security).
* **Transparent releases**: We use pnpm, Vite, GitHub Actions, and [npm package provenance](https://github.blog/security/supply-chain-security/introducing-npm-package-provenance/) for verifiable, reliable releases.
* **Frequent releases**: Regular releases ensure users get the latest security fixes and improvements promptly. Timely dependency updates also reduce the risk of vulnerabilities in third-party packages.
* **Publishing security**: [Trusted publishing](https://docs.npmjs.com/trusted-publishers) and [2FA](https://docs.npmjs.com/requiring-2fa-for-package-publishing-and-settings-modification) enabled.
* **Responsible disclosure**: We publish a [security policy](https://github.com/sveltia/sveltia-cms/security/policy) and encourage the responsible disclosure of vulnerabilities. We maintain a public list of [security advisories](https://github.com/sveltia/sveltia-cms/security/advisories) to keep users informed about issues and their resolutions. We give credit to security researchers who report vulnerabilities, although we do not offer bounties.
* **Swift response**: We prioritize security fixes and aim to address vulnerabilities within 12 hours of discovery, regardless of severity. In fact, we fixed the [first XSS vulnerability](https://github.com/sveltia/sveltia-cms/security/advisories/GHSA-97r8-rf7q-wmjw) reported to us in just two hours, despite it being low severity with no known exploits.

## What You Can Do

To protect your Sveltia CMS installation and data, follow these best practices:

* Keep your Sveltia CMS installation [up to date](/en/docs/releases). If you use the CDN version, you’ll always get the latest version unless you specify an exact version number in the URL. If you self-host, regularly check for updates and apply them promptly.
* Set up PKCE authentication for your Git backend if possible. Sveltia CMS supports quick PAT authentication, but it’s mainly for individual developers and not recommended for multi-user teams, especially when non-technical members are involved.
* Set up two-factor authentication (2FA) for your Git instance.
* Keep your Git instance up to date if you’re self-hosting it.
* Use HTTPS for your site to ensure secure communication between the client and server. All major hosting providers use HTTPS by default. If you self-host, consider using [Let’s Encrypt](https://letsencrypt.org/) to obtain free TLS certificates. Sveltia CMS doesn’t work on HTTP sites.
* Set up Content Security Policy (CSP) for your site. See the section below for recommended policies.
* Do not disable the `sanitize_preview` option for [RichText](/en/docs/fields/richtext) and [Markdown](/en/docs/fields/markdown) fields unless you fully understand the implications. Disabling this option may expose your site to XSS attacks if untrusted users can edit content.

## Setting up Content Security Policy

If your site adopts Content Security Policy (CSP), we recommend starting with the base policy below and adding origins for any additional features you use.

```
style-src 'self' 'unsafe-inline';
font-src 'self' https://cdn.jsdelivr.net;
img-src 'self' blob: data:;
media-src blob:;
frame-src blob:;
script-src 'self' https://unpkg.com;
connect-src 'self' blob: data: https://unpkg.com;
manifest-src blob:;
```

### Backends

#### GitHub

Also add your GitHub Enterprise Server origin if applicable.

* `img-src`
  ```
  https://*.githubusercontent.com
  ```
* `connect-src`
  ```
  https://api.github.com https://www.githubstatus.com
  ```

#### GitLab

Also add your self-hosted instance origin if applicable.

* `img-src`
  ```
  https://gitlab.com https://secure.gravatar.com
  ```
* `connect-src`
  ```
  https://gitlab.com https://status-api.hostedstatus.com
  ```

#### Gitea/Forgejo

Use your self-hosted instance origin instead if applicable.

* `img-src`
  ```
  https://gitea.com
  ```
* `connect-src`
  ```
  https://gitea.com
  ```

### Media Storage Providers

#### Cloudinary

Replace the img-src origin with your custom domain if configured.

* `img-src`
  ```
  https://res.cloudinary.com
  ```
* `frame-src`
  ```
  https://console.cloudinary.com
  ```

#### Uploadcare

Replace the img-src origin with your custom domain if configured.

* `img-src`
  ```
  https://*.ucarecd.net https://ucarecdn.com
  ```
* `connect-src`
  ```
  https://upload.uploadcare.com https://api.uploadcare.com
  ```

### Image Optimization

#### HEIC Conversion

Required if [HEIC photos](/en/docs/media#heic-photos) are converted on upload: the decoder runs in a Web Worker created from a `blob:` URL. Not required for the NPM package, which serves the worker from your site.

* `worker-src`
  ```
  blob:
  ```

### Stock Photo Providers

#### Lorem Picsum

* `img-src`
  ```
  https://picsum.photos https://fastly.picsum.photos
  ```
* `connect-src`
  ```
  https://picsum.photos
  ```

#### Pexels

* `img-src`
  ```
  https://images.pexels.com
  ```
* `connect-src`
  ```
  https://images.pexels.com https://api.pexels.com
  ```

#### Pixabay

* `img-src`
  ```
  https://pixabay.com
  ```
* `connect-src`
  ```
  https://pixabay.com
  ```

#### Unsplash

* `img-src`
  ```
  https://images.unsplash.com
  ```
* `connect-src`
  ```
  https://images.unsplash.com https://api.unsplash.com
  ```

### AI Integrations

#### Google Cloud Translation

* `connect-src`
  ```
  https://translation.googleapis.com
  ```

#### Google Gemini

* `connect-src`
  ```
  https://generativelanguage.googleapis.com
  ```

#### Anthropic

* `connect-src`
  ```
  https://api.anthropic.com
  ```

#### DeepSeek

* `connect-src`
  ```
  https://api.deepseek.com
  ```

#### Mistral AI

* `connect-src`
  ```
  https://api.mistral.ai
  ```

#### OpenAI

* `connect-src`
  ```
  https://api.openai.com
  ```

### Map Providers

#### OpenStreetMap

* `img-src`
  ```
  https://*.openstreetmap.org
  ```
* `connect-src`
  ```
  https://*.openstreetmap.org
  ```

### Video Embeds

#### YouTube

* `frame-src`
  ```
  https://www.youtube-nocookie.com
  ```

### CI/CD Providers

If you choose to [disable automatic deployments](/en/docs/deployments#disabling-automatic-deployments) and have configured a webhook URL, you may need to add the origin to the `connect-src` directive. Here are some examples:

#### Cloudflare Pages

* `connect-src`
  ```
  https://api.cloudflare.com
  ```

#### Netlify

* `connect-src`
  ```
  https://api.netlify.com
  ```

#### Vercel

* `connect-src`
  ```
  https://api.vercel.com
  ```

::: warning Breaking Change in v0.174.0

To ensure [GDPR compliance](https://github.com/sveltia/sveltia-cms/issues/443), we have replaced Google Fonts with [Fontsource](https://fontsource.org/) as the CMS’s font provider. If your site adopts a CSP, you may need to update your policy to allow the new font provider, which is served via jsDelivr. Specifically, you need to make the following changes:

* `style-src`: Remove `https://fonts.googleapis.com`
* `font-src`: Replace `https://fonts.gstatic.com` with `https://cdn.jsdelivr.net`

:::

::: tip Allowing All Image Sources

If you have image field(s) and expect that images will be inserted as URLs, you may want to allow any source using a wildcard instead of specifying individual origins:

```
img-src 'self' blob: data: https://*;
```

:::

::: tip Recommended CSP for Media Libraries

Please refer to the documentation for your specific storage provider for recommended CSP directives, as they typically depend on your configuration (e.g. custom domain vs default endpoint) and may require allowing specific origins for API calls and asset URLs.

:::

::: info Note for Netlify/Decap CMS users

Sveltia CMS does not require the `unsafe-eval` and `unsafe-inline` keywords in the `script-src` CSP directive. Also, the `script-src` CSP directive is not required for the Cloudinary integration to work, as we implemented it without using their hosted widget script.

:::

::: info About UNPKG origin

The [UNPKG](https://unpkg.com/) CDN is used for the following purposes in Sveltia CMS:

* Download the CMS script bundle
* Check for the latest version of the CMS
* Retrieve locale files for the admin interface other than English (US)
* Retrieve additional dependencies such as [PDF.js](https://github.com/mozilla/pdf.js), [Leaflet](https://github.com/Leaflet/Leaflet), and [SVGO](https://github.com/SVG/svgo)
* Retrieve the WebAssembly decoder for [HEIC photos](/en/docs/media#heic-photos) when image optimization is enabled
* Retrieve [Shiki](https://shiki.style/) language definitions and themes for syntax highlighting in code editors

The NPM package doesn’t use UNPKG for any of these. See below.

:::

::: tip CSP for the NPM Package

The [NPM package](/en/docs/releases#cdn-or-npm-package) serves all the files above, along with the fonts, from your own site. If you use it, you can remove `https://unpkg.com` and `https://cdn.jsdelivr.net` from the policy, and the HEIC conversion doesn’t need `blob:` in `worker-src`.

:::
