atomiks / tippyjs

Tooltip, popover, dropdown, and menu library
https://atomiks.github.io/tippyjs/
MIT License
11.86k stars 520 forks source link

Tippy breaks CSP Trusted Types #1041

Open tinganho opened 2 years ago

tinganho commented 2 years ago

Bug description

Tippy.js breaks CSP Trusted Types by using innerHTML assignment.

Reproduction

  1. Create a CSP Trusted Type site.
  2. Create a tippy tooltip.
  3. Provide a content which is of type HTMLElement.

CodePen link: https://codepen.io/tinganho/pen/GRyoaZO

atomiks commented 2 years ago

Is this just because the code uses .innerHTML? It's disabled by default, though, so you aren't exposed unless you explicitly enable it in the options. Doesn't React break too due to its dangerouslySetInnerHTML feature?

tinganho commented 2 years ago

You can set a policy for dangerouslySetInnerHTML, so it always go through a certain sanitizer.

For the tippy tooltip issue I noted it throws an error when it tries to empty an element:

image

I think it can be done with replaceChildren instead? https://developer.mozilla.org/en-US/docs/Web/API/Element/replaceChildren#emptying_a_node

tinganho commented 2 years ago

But, if you really have to use .innerHTML. What I noticed is that libraries use to provide their own trusted policies. Then consumers of those libs have to trust those policies.

IanVS commented 1 year ago

I'm hitting this issue as well, now that I'm trying to enable require-trusted-types-for 'script' in my CSP. (see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/require-trusted-types-for)

I believe the right way to handle this would be to create a trusted type as shown in MDN. Then, I could add this to my CSP as well and it would be fine: trusted-types tippy;, for example.

karlicoss commented 1 year ago

I'm having a related issue -- working on a browser extension and getting UNSAFE_VAR_ASSIGNMENT (Unsafe asssignment to innerHTML) while running web-ext lint.

Basically using innerHTML assingments in browser extension causes longer review times, and even possibly rejections.

Is there some suggested way/recipy to use the library without innerHTML codepaths? I'm not even using the functionality in my code, but it does end up bundled as part of setContent/createArrowElement functions.

Couple more links for the reference:

karlicoss commented 1 year ago

Seems that there is actually a comment in the code, introduced here regarding this issue with web extensions, but assigning innerHTML dynamically doesn't trick webext-lint anymore. And either way, it kinda goes against the idea of the lint check, so would be nice to find out a proper fix :)

karlicoss commented 1 year ago

Actually seems that headless tippy doesn't suffer from this innerHTML problem. And also generally seems less problematic for web extension because it doesn't inject extra CSS (so less chances to break sited with existing Tippy integrations)