Table of Contents
✅ 1. Avoid inline scripts and styles
✅ 2. Use a strict CSP header (without 'unsafe-inline')
Fix 'unsafe-eval'
✅ 3. Handle dynamic content safely
✅ 4. Use nonces or hashes for allowed scripts (if needed)
Example with nonce:
✅ 5. External resources and CDNs
✅ 6. Test your CSP
Summary: Best Practices
Home Web Front-end Vue.js How to handle content security policy (CSP) in a Vue SPA?

How to handle content security policy (CSP) in a Vue SPA?

Aug 03, 2025 am 08:56 AM

Avoid inline scripts and styles by moving all JavaScript to external files and using Vue’s event handlers instead of inline onclick attributes. 2. Use a strict CSP header without 'unsafe-inline' or 'unsafe-eval' by adopting Vue’s runtime-only build and Single File Components to eliminate the need for dynamic template compilation. 3. Handle dynamic content safely with v-html only after sanitizing user input using DOMPurify, ensuring CSP blocks script execution in injected HTML. 4. If inline scripts are necessary, use nonces or hashes instead of 'unsafe-inline', though this is best avoided in static SPAs unless using SSR. 5. Allow external resources like CDNs by explicitly specifying domains in CSP directives such as script-src, img-src, font-src, and connect-src, while avoiding 'unsafe-inline' for styles by using external or scoped CSS. 6. Test your CSP using browser dev tools, Google CSP Evaluator, and report-only mode to detect violations without enforcement, ensuring all policies work as intended before full deployment. By following these steps, a Vue SPA can operate under a strict Content Security Policy that effectively mitigates XSS and code injection risks without relying on unsafe directives, resulting in a secure and maintainable application.

How to handle content security policy (CSP) in a Vue SPA?

Handling Content Security Policy (CSP) in a Vue Single Page Application (SPA) is essential for securing your app against XSS (cross-site scripting) and other code injection attacks. However, Vue SPAs — especially those using dynamic features like inline scripts, eval(), or v-html — can easily conflict with strict CSP rules. Here’s how to handle CSP properly in a Vue SPA.

How to handle content security policy (CSP) in a Vue SPA?

✅ 1. Avoid inline scripts and styles

CSP blocks inline <script></script> and <style></style> tags by default. Vue itself doesn’t generate inline scripts when built properly, but common patterns can break CSP:

  • Avoid inline event handlers (@click, v-on) in templates — these are generally fine because Vue compiles them into event listeners, not inline onclick="".
  • Don’t use inline <script></script> tags in your index.html. Move all logic to external files.

❌ Bad (violates default CSP):

How to handle content security policy (CSP) in a Vue SPA?
<!-- index.html -->
<script>
  console.log('init');
</script>

✅ Good:

<!-- index.html -->
<script src="js/app.js"></script>

Use Webpack/Vite to bundle your Vue app and externalize all JavaScript.

How to handle content security policy (CSP) in a Vue SPA?

✅ 2. Use a strict CSP header (without 'unsafe-inline')

When deploying, set a strong CSP via HTTP headers (preferred) or <meta http-equiv="Content-Security-Policy">.

Example CSP header for a Vue SPA (hosted on same origin):

Content-Security-Policy: 
  default-src 'self';
  script-src 'self' 'unsafe-eval' 'unsafe-inline';  ← Avoid this!

Wait — you see 'unsafe-eval' and 'unsafe-inline'? That’s common during development but insecure.

Fix 'unsafe-eval'

Vue’s runtime compiler (template compilation in browser) uses new Function(), which triggers 'unsafe-eval'. To remove this:

➡️ Use the runtime-only build of Vue

In your Vue project (Vue 3 with Vite or Webpack), ensure you're using the runtime-only version:

// vite.config.js or webpack config
resolve: {
  alias: {
    'vue': 'vue/dist/vue.runtime.esm-bundler.js'
  }
}

And write your components using .vue files with <template>, not runtime templates like:

app.component('my-comp', { template: '<div>hi</div>' }) // needs compiler → needs unsafe-eval

✅ Instead, use SFCs (Single File Components):

<!-- MyComponent.vue -->
<template>
  <div>Hi</div>
</template>
<script>
export default {}
</script>

Now you can remove 'unsafe-eval' from script-src.


✅ 3. Handle dynamic content safely

Vue’s v-html directive can be dangerous and may require 'unsafe-inline' if misused.

❌ Avoid:

<div v-html="userContent"></div>

This opens XSS risks and doesn’t help CSP — CSP can’t distinguish safe vs unsafe v-html.

✅ Safer approach:

  • Sanitize user content with libraries like DOMPurify:
import DOMPurify from 'dompurify';

const cleanHTML = DOMPurify.sanitize(userHTML);
<div v-html="cleanHTML"></div>

Still, v-html doesn’t require relaxing CSP if you're not injecting inline scripts. CSP will block script execution in v-html content — which is good.

So: v-html is acceptable if you sanitize input and your CSP blocks script execution from DOM.


✅ 4. Use nonces or hashes for allowed scripts (if needed)

If you must include a safe inline script (e.g., early init code), use nonces or hashes instead of 'unsafe-inline'.

Example with nonce:

Generate a unique nonce per request on the server:

Content-Security-Policy: script-src 'self' 'nonce-abc123'

Then:

<script nonce="abc123">
  // small inline script
</script>

⚠️ This requires server-side rendering (SSR) or dynamic HTML generation. In a static Vue SPA, this is hard to implement unless you use SSR (Nuxt, etc.).

Alternatively, avoid inline scripts entirely — better for CSP and maintainability.


✅ 5. External resources and CDNs

If your Vue app loads external assets (fonts, analytics, APIs), update CSP accordingly.

Example:

Content-Security-Policy:
  default-src 'self';
  script-src 'self' https://www.m.sbmmt.com;
  img-src 'self' https://*.m.sbmmt.com;
  font-src 'self' https://fonts.gstatic.com;
  connect-src 'self' https://api.yourservice.com;
  style-src 'self' 'unsafe-inline'; ← minimize use

➡️ Avoid 'unsafe-inline' for style-src by:

  • Moving all CSS to external files (Vue handles this via scoped styles or CSS extraction).
  • Using style-src 'self' if all styles are bundled.

✅ 6. Test your CSP

Use browser dev tools (Security tab) to check CSP violations.

Also use:

  • Google CSP Evaluator
  • Report-only mode:
    Content-Security-Policy-Report-Only: default-src 'self'; report-uri /csp-report-endpoint

    This logs violations without blocking, great for testing.


    Summary: Best Practices

    • ✅ Use runtime-only Vue build to avoid 'unsafe-eval'
    • ✅ Avoid inline scripts/styles in index.html
    • ✅ Sanitize v-html content with DOMPurify
    • ✅ Use external bundles (Vite/Webpack) for all JS/CSS
    • ✅ Set CSP via HTTP headers: script-src 'self', no 'unsafe-inline' or 'unsafe-eval'
    • ✅ Allow only necessary external domains
    • ✅ Test CSP with Report-Only and browser tools

    Basically, with proper Vue setup and deployment hygiene, you can run a Vue SPA under a strict CSP — no unsafe flags needed. It just takes attention to how and where code is loaded.

    The above is the detailed content of How to handle content security policy (CSP) in a Vue SPA?. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undress AI Tool

Undress AI Tool

Undress images for free

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Hot Topics

PHP Tutorial
1510
276
Free entrance to Vue finished product resources website. Complete Vue finished product is permanently viewed online Free entrance to Vue finished product resources website. Complete Vue finished product is permanently viewed online Jul 23, 2025 pm 12:39 PM

This article has selected a series of top-level finished product resource websites for Vue developers and learners. Through these platforms, you can browse, learn, and even reuse massive high-quality Vue complete projects online for free, thereby quickly improving your development skills and project practice capabilities.

What are Vue lifecycle hooks? Name a few and explain their use cases. What are Vue lifecycle hooks? Name a few and explain their use cases. Jul 24, 2025 am 12:08 AM

The life cycle hook of the Vue component is used to execute code at a specific stage. 1.created: Called immediately after the component is created, suitable for initializing data; 2.mounted: Called after the component is mounted to the DOM, suitable for operating the DOM or loading external resources; 3.updated: Called when the data update causes the component to be re-rendered, suitable for responding to data changes; 4.beforeUnmount: Called before the component is uninstalled, suitable for cleaning event listening or timer to prevent memory leakage. These hooks help developers accurately control component behavior and optimize performance.

Example of a pagination component in Vue Example of a pagination component in Vue Jul 26, 2025 am 08:49 AM

To implement reusable Vue paging components, the following key points need to be clarified: 1. Define props including the total number of lines, the number of lines per page and the current page number; 2. Calculate the total number of pages; 3. Dynamically generate the displayed page number array; 4. Process the page number click event and pass it to the parent component; 5. Add styles and interaction details. Receive data through props and set default values, use the computed attribute to calculate the total number of pages, use the method to generate the currently displayed page number array, render buttons in the template and bind click events to trigger the update:current-page event, listen to the event in the parent component to update the current page number, and finally highlight the current page number through CSS and control the button status to improve the user experience.

vue free finished product resource entrance vue free finished product website navigation vue free finished product resource entrance vue free finished product website navigation Jul 23, 2025 pm 12:42 PM

For Vue developers, a high-quality finished project or template is a powerful tool to quickly start new projects and learn best practices. This article has selected multiple top Vue free finished product resource portals and website navigation for you to help you find the front-end solutions you need efficiently, whether it is a back-end management system, UI component library, or templates for specific business scenarios, you can easily obtain them.

How to use $ref compiler macro? How to use $ref compiler macro? Jul 19, 2025 am 01:27 AM

$ref is a keyword used to reference other parts of a JSON or YAML configuration file or external file structure, commonly found in JSONSchema and OpenAPI specifications. 1. The basic syntax of $ref is {"$ref":"path"}, which can point to the internal inside of the current document (such as #/definitions/User) or external files (such as user-schema.json#/definitions/User). 2. Usage scenarios include reusing schemas, splitting large files, and organizing code structures. 3. Note that the path must be correct, avoid circular references, ensure that external files are accessible, and avoid excessive nesting.

How to use slots and named slots in a Vue component? How to use slots and named slots in a Vue component? Jul 21, 2025 am 03:24 AM

Using slots and named slots in Vue can improve component flexibility and reusability. 1. The slot allows the parent component to insert content into the child component through a tag, such as inserting paragraph text into the Card.vue component; 2. The named slot realizes control of the content insertion position through the name attribute, such as defining the header, body and footer areas respectively in the modal box component; 3. The default content can be set in the slot as an alternative when the parent component is not provided, such as the default close button; 4. The # symbol is the abbreviation syntax of v-slot:; 5. It is recommended to use slots reasonably to avoid excessive dependence, and some content can be considered to be implemented through props or scope components.

How to implement internationalization (i18n) in a Vue app? How to implement internationalization (i18n) in a Vue app? Jul 26, 2025 am 08:37 AM

Install VueI18n: Vue3 uses npminstallvue-i18n@next, Vue2 uses npminstallvue-i18n; 2. Create language files such as en.json and es.json in the locales directory, supporting nested structures; 3. Create instances through createI18n in Vue3 and mount them in main.js, Vue2 uses Vue.use(VueI18n) and instantiate VueI18n; 4. Use {{$t('key')}} interpolation in templates, use useI18n's t function in Vue3Composition API, and Vue2Options API

Computed properties vs methods in Vue Computed properties vs methods in Vue Aug 05, 2025 am 05:21 AM

Computed has a cache, and multiple accesses are not recalculated when the dependency remains unchanged, while methods are executed every time they are called; 2.computed is suitable for calculations based on responsive data. Methods are suitable for scenarios where parameters are required or frequent calls but the result does not depend on responsive data; 3.computed supports getters and setters, which can realize two-way synchronization of data, but methods are not supported; 4. Summary: Use computed first to improve performance, and use methods when passing parameters, performing operations or avoiding cache, following the principle of "if you can use computed, you don't use methods".

See all articles