stoplightio / elements

Build beautiful, interactive API Docs with embeddable React or Web Components, powered by OpenAPI and Markdown.
https://stoplight.io/open-source/elements/
Apache License 2.0
1.7k stars 196 forks source link

Inline styles in web-components.min.js cause CSP violation #2506

Open PatrickSchuster opened 7 months ago

PatrickSchuster commented 7 months ago

I have a CSP which sets style-src 'self' 'sha256-...'.

Unfortunately, I cannot add the sha256 hash that Chrome calculated to my CSP since it keeps changing and therefore I keep running into the same violation.

Context

I'm trying to have a strict CSP while using stoplight.

Current Behavior

I'm using https://unpkg.com/@stoplight/elements@8.0.0/web-components.min.js which seem to to cause a CSP violation: Refused to apply inline style because it violates the following Content Security Policy directive: "style-src 'self' 'sha256-....

Screenshot 2024-01-17 at 13 16 46

Expected Behavior

There are no more CSP violations while using the library.

Possible Solution(s)

Are there any plans to get rid of inline styles to avoid CSP violations? I'm a bit hesitant to weaken my CSP by using script-src 'unsafe-inline'.

Thank you!

billiegoose commented 7 months ago

Are there any plans to get rid of inline styles to avoid CSP violations?

It appears that CSP is a challenge to get working with any Web Components that utilize inline CSS. I found this discussion which seems to indicate that there is currently no trivial way to get the benefits of web components in a CSP compatible way. How frustrating.

But... where are the inline styles coming from? Any idea? I (wrongly) assumed that since some of the CSS is bundled in a separate file...

https://github.com/stoplightio/elements/blob/3e17d6330c8406983cd81401eb93a15af5e960cd/examples/static-html/zoom-api/index.html#L10-L13

that ALL of it was bundled in a separate file, but clearly that's not the case.

@PatrickSchuster any chance you can provide a working reproduction, perhaps by modifying the static-html demo referenced above? I gotta go brush up on CSP...

billiegoose commented 7 months ago

oooooooooh it might be our usage of Font Awesome icons... image

PatrickSchuster commented 7 months ago

Hi @billiegoose and thank you for your detailed response!

Here is a minimal reproducable example that is very similar to my project:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <title>Inline styles VS CSP demo</title>
    <meta name="description" content="Example site using Stoplight Elements along with a CSP in the meta element to highlight violations"/>
    <meta name="author" content="Patrick"/>
    <meta http-equiv="Content-Security-Policy" content="style-src 'self' 'sha256-MBVp6JYxbC/wICelYC6eULCRpgi9kGezXXSaq/TS2+I=';">
    <script src="web-components.min.js"></script>
    <link rel="stylesheet" href="styles.min.css">
</head>
<body>
    <elements-api
      apiDescriptionUrl="https://api.apis.guru/v2/specs/github.com/1.1.4/openapi.yaml"
      router="hash"
      layout="sidebar"
    />
</body>
</html>

(Make sure to click on the "Update a webhook confugration" endpoint to see an error.)

Notice that I added a hash (sha256-...) that chrome reported. There are still issues though regarding inline styles that cannot seem to be fixed by adding more hashes as they are not static and therefore change on every page reload.

Also notice that I reference the:

locally. While they can be hosted separetly I wanted to share an example that is as close to my original project as possible.

I know that CSP is frustrating and is tricky to add especially when working with 3rd party software. Still, it is required in my project for security reasons and I wanted to point out the issues I found.

Screenshot 2024-01-22 at 12 51 13 Screenshot 2024-01-22 at 12 51 23

Btw, as a very "caveman-like" workaround I added some code to the locally hosted web-components.min.js exactly where chrome highlights the error (...t ? n.insertBefore(e, t) : n.appendChild(e);...) which naively checks the elements inline CSS against a CSS value I store in a map. If there is a match, it references the same CSS code (which I copied to a locally served external CSS style file) and removes the inline style from the html element. I know, this is an ugly hack but seemed to have helped at least somewhat as I had to make sure there is a strict CSP and the documentation page still doesn't look completely broken...

Thank you and BR!

github-actions[bot] commented 7 months ago

This ticket has been labeled jira. A tracking ticket in Stoplight's Jira (STOP-91) has been created.