ionicons icon indicating copy to clipboard operation
ionicons copied to clipboard

fetch for SVG source result in CSP violations.

Open billxinli opened this issue 3 years ago • 5 comments

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?

billxinli avatar Nov 29 '21 21:11 billxinli

Thanks. Can you provide a GitHub repo I can use to reproduce this issue?

liamdebeasi avatar Feb 03 '22 16:02 liamdebeasi

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

cjorasch avatar Apr 22 '22 00:04 cjorasch

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.

mezoistvan avatar May 13 '22 18:05 mezoistvan

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>

rafaelbatistamarcilio avatar Jun 08 '22 02:06 rafaelbatistamarcilio

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.

deptford avatar Jun 23 '22 09:06 deptford

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

dtarnawsky avatar Oct 03 '22 17:10 dtarnawsky

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.

liamdebeasi avatar Nov 08 '22 19:11 liamdebeasi