home / skills / dchuk / claude-code-tauri-skills / tauri-csp

tauri-csp skill

/tauri/tauri-csp

This skill helps you securely configure CSP in Tauri v2 apps to prevent XSS and control resource loading.

npx playbooks add skill dchuk/claude-code-tauri-skills --skill tauri-csp

Review the files below or copy the command above to add this skill to your agents.

Files (1)
SKILL.md
8.7 KB
---
name: configuring-tauri-csp
description: Guides users through configuring Content Security Policy (CSP) in Tauri v2 applications to prevent XSS attacks and enhance security by restricting resource loading.
---

# Tauri Content Security Policy (CSP) Configuration

This skill covers Content Security Policy configuration for Tauri v2 desktop applications.

## Why CSP Matters in Tauri

CSP is a security mechanism that mitigates common web vulnerabilities in Tauri applications:

1. **XSS Prevention**: Restricts which scripts can execute, blocking injected malicious code
2. **Resource Control**: Limits where the WebView can load assets from (scripts, styles, images, fonts)
3. **Trust Boundaries**: Strengthens the isolation between frontend WebView and backend Rust code
4. **Attack Surface Reduction**: Prevents unauthorized network connections and resource loading

Tauri operates on a trust boundary model where frontend code has limited access to system resources through a well-defined IPC layer. CSP adds an additional layer of protection within the frontend trust zone.

## How Tauri Implements CSP

Tauri uses a two-part protection strategy:

1. **Local Scripts**: Protected through cryptographic hashing at compile time
2. **Styles and External Scripts**: Verified using nonces

Tauri automatically appends nonces and hashes to bundled code during compilation. Developers only need to configure application-specific trusted sources.

**Important**: CSP protection only activates when explicitly configured in the Tauri configuration file.

## Default CSP Behavior

By default, Tauri does not apply a CSP. You must explicitly configure it in `tauri.conf.json` under the `security` section:

```json
{
  "security": {
    "csp": null
  }
}
```

When `csp` is `null` or omitted, no Content Security Policy is enforced.

## Basic CSP Configuration

### Minimal Secure Configuration

```json
{
  "security": {
    "csp": {
      "default-src": "'self'"
    }
  }
}
```

This restricts all resources to the same origin only.

### Recommended Configuration

```json
{
  "security": {
    "csp": {
      "default-src": "'self' customprotocol: asset:",
      "connect-src": "ipc: http://ipc.localhost",
      "font-src": ["https://fonts.gstatic.com"],
      "img-src": "'self' asset: http://asset.localhost blob: data:",
      "style-src": "'unsafe-inline' 'self' https://fonts.googleapis.com"
    }
  }
}
```

## Common CSP Directives for Tauri

### default-src

Fallback policy for all resource types not explicitly defined.

```json
"default-src": "'self' customprotocol: asset:"
```

Common values:
- `'self'` - Same origin only
- `'none'` - Block all resources
- `customprotocol:` - Tauri custom protocol
- `asset:` - Tauri asset protocol

### script-src

Controls which scripts can execute.

```json
"script-src": "'self'"
```

For WebAssembly or Rust-based frontends (Leptos, Yew, Dioxus):

```json
"script-src": "'self' 'wasm-unsafe-eval'"
```

**Warning**: Never use `'unsafe-eval'` unless absolutely required.

### style-src

Controls stylesheet sources.

```json
"style-src": "'self' 'unsafe-inline' https://fonts.googleapis.com"
```

Note: `'unsafe-inline'` is often needed for CSS-in-JS libraries but reduces security.

### connect-src

Controls allowed connection destinations for fetch, WebSocket, etc.

```json
"connect-src": "ipc: http://ipc.localhost https://api.example.com"
```

Tauri-specific:
- `ipc:` - Inter-process communication with Rust backend
- `http://ipc.localhost` - Alternative IPC endpoint

### img-src

Controls image loading sources.

```json
"img-src": "'self' asset: http://asset.localhost blob: data:"
```

Common values:
- `blob:` - Blob URLs (for dynamically created images)
- `data:` - Data URLs (base64 encoded images)
- `asset:` - Tauri asset protocol

### font-src

Controls font loading sources.

```json
"font-src": "'self' https://fonts.gstatic.com"
```

### frame-src

Controls iframe sources.

```json
"frame-src": "'none'"
```

Recommended to block all frames unless specifically needed.

### object-src

Controls plugin content (Flash, Java, etc.).

```json
"object-src": "'none'"
```

Always set to `'none'` for modern applications.

## Configuration Format Options

### Object Format (Recommended)

```json
{
  "security": {
    "csp": {
      "default-src": "'self'",
      "script-src": "'self' 'wasm-unsafe-eval'",
      "style-src": "'self' 'unsafe-inline'"
    }
  }
}
```

### Array Format for Multiple Sources

```json
{
  "security": {
    "csp": {
      "font-src": ["'self'", "https://fonts.gstatic.com", "https://fonts.googleapis.com"]
    }
  }
}
```

### String Format

```json
{
  "security": {
    "csp": "default-src 'self'; script-src 'self'"
  }
}
```

## Framework-Specific Configurations

### React/Vue/Svelte (Standard JS Frameworks)

```json
{
  "security": {
    "csp": {
      "default-src": "'self'",
      "script-src": "'self'",
      "style-src": "'self' 'unsafe-inline'",
      "img-src": "'self' data: blob:",
      "font-src": "'self'",
      "connect-src": "ipc: http://ipc.localhost"
    }
  }
}
```

### Leptos/Yew/Dioxus (Rust/WASM Frameworks)

```json
{
  "security": {
    "csp": {
      "default-src": "'self'",
      "script-src": "'self' 'wasm-unsafe-eval'",
      "style-src": "'self' 'unsafe-inline'",
      "img-src": "'self' data: blob:",
      "font-src": "'self'",
      "connect-src": "ipc: http://ipc.localhost"
    }
  }
}
```

### With External APIs

```json
{
  "security": {
    "csp": {
      "default-src": "'self'",
      "script-src": "'self'",
      "connect-src": "ipc: http://ipc.localhost https://api.example.com wss://ws.example.com",
      "img-src": "'self' https://cdn.example.com"
    }
  }
}
```

## Security Best Practices

### 1. Avoid Remote Scripts

Never load scripts from CDNs in production:

```json
// AVOID - introduces attack vector
"script-src": "'self' https://cdn.jsdelivr.net"

// PREFERRED - bundle all dependencies
"script-src": "'self'"
```

### 2. Minimize unsafe-inline

Only use `'unsafe-inline'` when required by your framework:

```json
// More secure
"style-src": "'self'"

// Less secure but sometimes necessary
"style-src": "'self' 'unsafe-inline'"
```

### 3. Use Restrictive Defaults

Start restrictive and add permissions as needed:

```json
{
  "security": {
    "csp": {
      "default-src": "'none'",
      "script-src": "'self'",
      "style-src": "'self'",
      "img-src": "'self'",
      "font-src": "'self'",
      "connect-src": "ipc: http://ipc.localhost"
    }
  }
}
```

### 4. Block Dangerous Features

Always block unused dangerous features:

```json
{
  "security": {
    "csp": {
      "object-src": "'none'",
      "base-uri": "'self'",
      "form-action": "'self'"
    }
  }
}
```

## Advanced Configuration

### Disabling CSP Modifications

If you need full control over CSP (not recommended):

```json
{
  "security": {
    "csp": {
      "default-src": "'self'"
    },
    "dangerousDisableAssetCspModification": true
  }
}
```

**Warning**: This disables Tauri's automatic nonce and hash injection.

### Freeze Prototype

Additional XSS protection by freezing JavaScript prototypes:

```json
{
  "security": {
    "csp": {
      "default-src": "'self'"
    },
    "freezePrototype": true
  }
}
```

## Troubleshooting

### Resources Blocked by CSP

Check browser DevTools console for CSP violation messages. They indicate which directive is blocking the resource.

Example error:
```
Refused to load the script 'https://example.com/script.js' because it violates the following Content Security Policy directive: "script-src 'self'"
```

Solution: Add the domain to the appropriate directive:
```json
"script-src": "'self' https://example.com"
```

### WebAssembly Not Loading

Add `'wasm-unsafe-eval'` to script-src:
```json
"script-src": "'self' 'wasm-unsafe-eval'"
```

### Inline Styles Not Working

For CSS-in-JS libraries, add `'unsafe-inline'` to style-src:
```json
"style-src": "'self' 'unsafe-inline'"
```

### IPC Not Working

Ensure connect-src includes Tauri IPC endpoints:
```json
"connect-src": "ipc: http://ipc.localhost"
```

## Complete Example Configuration

```json
{
  "productName": "my-tauri-app",
  "version": "1.0.0",
  "security": {
    "csp": {
      "default-src": "'self' customprotocol: asset:",
      "script-src": "'self'",
      "style-src": "'self' 'unsafe-inline'",
      "img-src": "'self' asset: http://asset.localhost blob: data:",
      "font-src": "'self'",
      "connect-src": "ipc: http://ipc.localhost",
      "object-src": "'none'",
      "base-uri": "'self'",
      "form-action": "'self'",
      "frame-ancestors": "'none'"
    },
    "freezePrototype": true
  }
}
```

## References

- [Tauri CSP Documentation](https://v2.tauri.app/security/csp)
- [Tauri Security Overview](https://v2.tauri.app/security/)
- [Tauri SecurityConfig Reference](https://v2.tauri.app/reference/config/#securityconfig)

Overview

This skill guides you through configuring Content Security Policy (CSP) for Tauri v2 desktop applications to reduce XSS risk and control resource loading. It explains default behavior, recommended directives, framework-specific adjustments, and how to enable Tauri’s nonce/hash protections. Use it to harden the frontend trust zone and limit what the WebView can fetch or execute.

How this skill works

The skill inspects Tauri security configuration patterns and explains how to set the security.csp field in tauri.conf.json using object, array, or string formats. It covers Tauri’s automatic nonce and hash injection for local scripts and nonces for styles, and highlights options like freezePrototype and dangerousDisableAssetCspModification. Troubleshooting tips show how to read CSP violation messages and adjust directives.

When to use it

  • When creating or reviewing a Tauri v2 app to prevent XSS and unsafe resource loading.
  • Before shipping production builds to ensure remote scripts and dangerous features are blocked.
  • When integrating WASM or Rust frontends that require 'wasm-unsafe-eval'.
  • When using CSS-in-JS or other libraries that need inline styles.
  • When configuring IPC and external API connections for the app.

Best practices

  • Start restrictive (default-src 'none' or 'self') and add only required sources.
  • Avoid loading remote scripts from CDNs in production; bundle dependencies instead.
  • Minimize use of 'unsafe-inline' and never use 'unsafe-eval' unless absolutely required.
  • Explicitly block plugin and framing features (object-src 'none', frame-ancestors 'none').
  • Include Tauri IPC endpoints in connect-src (ipc: and http://ipc.localhost) for backend comms.

Example use cases

  • Standard React/Vue/Svelte app: default-src 'self', script-src 'self', style-src 'self' 'unsafe-inline', connect-src ipc:
  • Rust/WASM frontend (Leptos/Yew/Dioxus): script-src includes 'wasm-unsafe-eval' for WASM loading.
  • App that contacts external APIs: add specific https:// and wss:// endpoints to connect-src only.
  • Image-heavy app: allow asset:, blob:, and data: in img-src while keeping other sources tight.
  • High-security desktop app: enable freezePrototype and set dangerous features to 'none'.

FAQ

What happens if I leave csp null or omit it?

No Content Security Policy is enforced by Tauri; you must set security.csp to enable protections.

How do I allow WebAssembly in my frontend?

Add 'wasm-unsafe-eval' to script-src to permit WASM evaluation required by some Rust/WASM frameworks.

Why are resources blocked after adding CSP?

Check DevTools CSP violation messages, then add the specific domain or protocol to the relevant directive (e.g., script-src or img-src).