Description
Applications enforcing a Strict Content Security Policy (CSP) (without 'unsafe-inline') are experiencing console errors and broken exports (SVG/PNG). This is caused by the dynamic injection of a <style> block inside a foreignObject during the export process, this behavior was recently updated in commit 9ce4d0c.
Code
File: src/modules/Exports.js Lines: 78-80
<style type="text/css">
${exportStyles}
</style>
Versions
- ApexCharts: ^5.3.6
- Vue3-ApexCharts: ^1.10.0
- Environment: Vue 3 (Composition API) with strict Content Security Policy.
Steps to Reproduce
- Use a Vue 3 application with vue3-apexcharts (or Vanilla ApexCharts).
- Set a strict CSP via Meta tag:
- Render a chart with a legend enabled.
- Trigger the "Export to SVG" or "Export to PNG" via the toolbar or direct method call.
- Check the Browser Console.
Expected Behavior
The chart should export successfully without violating security policies. Styles should be applied via SVG attributes (e.g., fill, stroke, display) instead of an injected <style> string, or the library should provide a way to pass a nonce to the export styles.
Actual Behavior
The browser blocks the style injection, throwing a CSP violation error, often resulting in unstyled exports or failed downloads.
Screenshots
Evidence of Awareness (Commit 9ce4d0c)
The internal test file browser-sync-config.js confirms the developers were aware of this restriction, as they manually added a nonce to the test environment:
const TEST_NONCE = '47ebaa88ef82ffb86e4ccb0...'
const cspPolicies = [`style-src 'self' 'nonce-${TEST_NONCE}'`]
However, the exported SVG and PNG does not inherit any application-level nonce, making this fix unavailable for end-users.
Suggested Fixes
-
(Preferred): Move essential export styles from a <style> block to inline SVG attributes (e.g., fill="...", stroke="...", display="none") on the elements themselves. SVG attributes are not restricted by style-src 'unsafe-inline'.
-
(Opt-in): Provide a configuration flag (e.g., chart.export.ignoreStyles) to allow a "CSS-free" export for strict CSP environments, with default width and height etc...
-
(Nonce Support): Allow passing a cspNonce through the chart configuration to be injected into the generated <style> tag.
Reproduction Link
https://codesandbox.io/p/sandbox/vue-basic-example-forked-3cw8zf?file=%2Findex.html%3A18%2C8
Description
Applications enforcing a Strict Content Security Policy (CSP) (without 'unsafe-inline') are experiencing console errors and broken exports (SVG/PNG). This is caused by the dynamic injection of a <style> block inside a foreignObject during the export process, this behavior was recently updated in commit 9ce4d0c.
Code
File: src/modules/Exports.js Lines: 78-80
Versions
Steps to Reproduce
Expected Behavior
The chart should export successfully without violating security policies. Styles should be applied via SVG attributes (e.g., fill, stroke, display) instead of an injected <style> string, or the library should provide a way to pass a nonce to the export styles.
Actual Behavior
The browser blocks the style injection, throwing a CSP violation error, often resulting in unstyled exports or failed downloads.
Screenshots
Evidence of Awareness (Commit 9ce4d0c)
The internal test file browser-sync-config.js confirms the developers were aware of this restriction, as they manually added a nonce to the test environment:
However, the exported SVG and PNG does not inherit any application-level nonce, making this fix unavailable for end-users.
Suggested Fixes
(Preferred): Move essential export styles from a <style> block to inline SVG attributes (e.g., fill="...", stroke="...", display="none") on the elements themselves. SVG attributes are not restricted by style-src 'unsafe-inline'.
(Opt-in): Provide a configuration flag (e.g., chart.export.ignoreStyles) to allow a "CSS-free" export for strict CSP environments, with default width and height etc...
(Nonce Support): Allow passing a cspNonce through the chart configuration to be injected into the generated <style> tag.
Reproduction Link
https://codesandbox.io/p/sandbox/vue-basic-example-forked-3cw8zf?file=%2Findex.html%3A18%2C8