ionicons
ionicons copied to clipboard
fetch for SVG source result in CSP violations.
It looks like the icons are loaded with fetch
via data:
schema
https://github.com/ionic-team/ionicons/blob/main/src/components/icon/request.ts#L13
With Content Security Policy
headers enabled, the connect-src
directive will block the icons from loading, unless if we also allow data:
source.
However, this is not a safe practice. https://security.stackexchange.com/questions/94993/is-including-the-data-scheme-in-your-content-security-policy-safe
Refused to connect to 'data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' class='ionicon' viewBox='0 0 512 512'><title>Calendar</title><rect stroke-linejoin='round' x='48' y='80' width='416' height='384' rx='48' class='ionicon-fill-none ionicon-stroke-width'/><circle cx='296' cy='232' r='24'/><circle cx='376' cy='232' r='24'/><circle cx='296' cy='312' r='24'/><circle cx='376' cy='312' r='24'/><circle cx='136' cy='312' r='24'/><circle cx='216' cy='312' r='24'/><circle cx='136' cy='392' r='24'/><circle cx='216' cy='392' r='24'/><circle cx='296' cy='392' r='24'/><path stroke-linejoin='round' stroke-linecap='round' d='M128 48v32M384 48v32' class='ionicon-fill-none ionicon-stroke-width'/><path stroke-linejoin='round' d='M464 160H48' class='ionicon-fill-none ionicon-stroke-width'/></svg>' because it violates the following Content Security Policy directive: "connect-src 'self' *.example.com".
I am curious, why is fetch
used to load local resources?
Thanks. Can you provide a GitHub repo I can use to reproduce this issue?
We are running into the same issue. I am not sure it is something that can easily be put into a GitHub repo because it relates to the CSP headers for the server hosting the web application that uses ionic vs. the application code.
If CSP is allowed to fetch anything then that could introduce security risks for the application beyond ion-icon usage (e.g. XSS).
A simplified version of what we were using in the header is:
content-security-policy: connect-src 'self' https://*.mydomain.com
Here is the error:
Refused to connect to 'data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' class='ionicon' viewBox='0 0 512 512'><path d='M384 224v184a40 40 0 01-40 40H104a40 40 0 01-40-40V168a40 40 0 0140-40h167.48' stroke-linecap='round' stroke-linejoin='round' class='ionicon-fill-none ionicon-stroke-width'/><path d='M459.94 53.25a16.06 16.06 0 00-23.22-.56L424.35 65a8 8 0 000 11.31l11.34 11.32a8 8 0 0011.34 0l12.06-12c6.1-6.09 6.67-16.01.85-22.38zM399.34 90L218.82 270.2a9 9 0 00-2.31 3.93L208.16 299a3.91 3.91 0 004.86 4.86l24.85-8.35a9 9 0 003.93-2.31L422 112.66a9 9 0 000-12.66l-9.95-10a9 9 0 00-12.71 0z'/></svg>' because it violates the following Content Security Policy directive: "connect-src 'self' https://*.mydomain.com".
In this case the icons fail because it is trying to fetch data:image/svg+xml;utf8...
which fails the CSP criteria even though it does not actually make a network request.
I think ionic added the code to be able to bundle icons in the code vs. as external files. Instead of using fetch you could simply use a regex or string patterns to get the svg content without a fetch and avoid any CSP problems.
Longer term it could also be made more efficient with bypassing intersection observers, creating Dom nodes to get the innerHTML, etc.
We were able to get around the issue by changing the CSP header but I am worried about potential security risks. It works with:
content-security-policy: connect-src 'self' data: https://*.mydomain.com
Here is a good discussion of risks associated with data:
content: https://security.stackexchange.com/questions/94993/is-including-the-data-scheme-in-your-content-security-policy-safe
We also experienced this issue after updating our Ionic 5 app to Ionic 6. We were able to modify the CSP header, but we are worried about the security risks. It would be great if there was an other solution to this issue.
There is another solution without enable "content-security-policy: connect-src 'self' data:"
change <ion-icon name="icon-name">
for <ion-icon src="/svg/icon-name.svg">
and replace <ion-menu-button> </ion-menu-button>
for
<ion-menu-toggle>
<ion-icon src="/svg/menu.svg"></ion-icon>
<ion-menu-toggle>
We also have this issue after upgrading to ionic 6. As mentioned in the link on the first post, the way the icons are defined + loaded clashes with a recommended secure CSP policy (ie not using the data: scheme in connect-src). The icons themselves are defined in @ionic/core/components and are all of the form:
const reorderThreeOutline = "data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' class='ionicon'...
This obviously isn't an issue unique to ionic but would appreciate a way to implement a secure CSP policy for serving ionic icons for PWAs.
Thanks. Can you provide a GitHub repo I can use to reproduce this issue?
Hey Liam,
I've created a sample reproduction here: https://github.com/dtarnawsky/cs-back-button-csp
Thanks for the issue. This has been resolved via https://github.com/ionic-team/ionicons/pull/1141, and a fix will be available in an upcoming release of Ionicons. Ionic Framework will also be updated to advantage of this fix.