ui icon indicating copy to clipboard operation
ui copied to clipboard

Add Nonce support to prevent XSS attacks

Open wiesty opened this issue 11 months ago • 4 comments

Certain UI elements in the UI library, like Toast and NavMenu, lack nonce support. Nonces, or Number Used Once, are essential for Content Security Policy (CSP) to prevent XSS attacks by allowing only specific scripts to execute. Enhancing the UI library to include nonce functionality for these elements would align with security best practices and bolster protection against XSS attacks. See Next.js documentation for more details on nonces and CSP. This issue aims to address this gap, ensuring a more secure environment for Next.js/React applications.

Either add nonce support or remove the inline style css. (this would fix it too!)

wiesty avatar Mar 02 '24 16:03 wiesty

Can you provide an example please? Not sure what you mean by inline style in this context. Thank you.

shadcn avatar Mar 03 '24 11:03 shadcn

An example would be toast:

Pre-information:

cspHeader:

const cspHeader = " default-src 'self'; script-src 'self' 'nonce-${nonce}' 'strict-dynamic'; style-src 'self' 'nonce-${nonce}'; img-src 'self' blob: data: ${process.env.CMS_DOMAIN}; font-src 'self'; object-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'none'; block-all-mixed-content; upgrade-insecure-requests; " As you can see, a nonce is required for elements with inline styling.

I am importing the toaster via:

import { Toaster } from "@/components/ui/toaster"; and <Toaster nonce={nonce ?? ""}/> <-- I am trying to set the generated header nonce from the csp middleware.

Also, I am using TypeScript and it tells me:

"The type "{ nonce: string; }" cannot be assigned to the type "IntrinsicAttributes". The property "nonce" is not present for the type "IntrinsicAttributes".

The rendered toaster element should look like this in the browser:

<div role="region" aria-label="Notifications (F8)" tabindex="-1" style="pointer-events:none"> <ol tabindex="-1" class="fixed top-0 z-[100] flex max-h-screen w-full flex-col-reverse p-4 sm:bottom-0 sm:right-0 sm:top-auto sm:flex-col md:max-w-[420px]"></ol> </div>

Here you can see that there is an inline style tag. Because I am not able to add the nonce like I tried above, the element gets flagged by the content security policy.

It should look in the end browser like this:

<div role="region" aria-label="Notifications (F8)" tabindex="-1" nonce="NTUxMDI1xxxx...." style="pointer-events:none"> <ol tabindex="-1" class="fixed top-0 z-[100] flex max-h-screen w-full flex-col-reverse p-4 sm:bottom-0 sm:right-0 sm:top-auto sm:flex-col md:max-w-[420px]"></ol> </div> (passing the nonce)

Somehow some elements are able to use the provided nonce like ThemeProvider, but the toaster doesn't. Please correct me if I've done anything wrong or misunderstood anything. 👍🏻

wiesty avatar Mar 03 '24 18:03 wiesty

Hello.

Im getting similar problem with some Shadcn components. I noticed that dynamic elements like Dialog, Sheet and Tabs gives me the error when i set my Content Security Policy directive: "style-src 'self' 'nonce...:

Refused to apply inline style because it violates the following Content Security Policy directive: "style-src 'self' 'nonce-i9t0qRM9nCj0iun6ASdsa0Yz16c0M3Iaadas='". Either the 'unsafe-inline' keyword, a hash ('sha256-MtxTdfsVEJSDALEIqblYS='), or a nonce ('nonce-...') is required to enable inline execution. Note that hashes do not apply to event handlers, style attributes and javascript: navigations unless the 'unsafe-hashes' keyword is present.

image

To be more specific, when I press the trigger button to open a Dialog or a Sheet this error pops on my console. In other hand, the Tab component logs this error just by been rendered.

My app uses nonce and my directive for Content Security Policy (CSP) has "style-src 'self' 'nonce'. Without this directive I have no errors but this is a very important one.

Here is the module tracing to this error: image

image

joaoguidev avatar Mar 05 '24 23:03 joaoguidev

Any updates on this issue? I am also experiencing it, same output as the comment before whilst trying to use a command component. It looks like they are all stemming from the singleton.js from react-style-singleton. This has made it very difficult, I have tried all possible solutions but they don't work. Even with the Using nonces with Next.JS update and the strict example.

image

discoverlance-com avatar Apr 23 '24 23:04 discoverlance-com

Also experiencing this same issue that comes down to this insertStyleTag function, besides using unsafe-inline , I don't know if there's a way around this?

WoetDev avatar May 05 '24 10:05 WoetDev

This issue has been automatically closed because it received no activity for a while. If you think it was closed by accident, please leave a comment. Thank you.

shadcn avatar Jun 11 '24 23:06 shadcn

Is this solved?

WoetDev avatar Jul 10 '24 11:07 WoetDev

This is problematic. I'm also experiencing the same issue.

devnull avatar Jul 22 '24 04:07 devnull

@shadcn still not fixed. Reopen this please

wiesty avatar Jul 23 '24 07:07 wiesty

I believe this is only an issue with the Vaul library (used by the Drawer component). Vaul injects inline scripts and styles. I think that nonces should not be used in production.

To solve this I simply stopped using that component.

If you use vite when working with shadcn, you can enable nonces specifically in dev mode which fixes CSP issues there.

rolznz avatar Aug 10 '24 04:08 rolznz

It isn’t an issue with just the Vaul library. I think this is actually an issue with multiple components part of radix. Dialog, Select, Command, Drawer, and probably others but I didn’t check any more. Any injection of scripts and modification of inline styles was too much of a risk, so unfortunately I ended up changing UI components.

Agreed, nonce is not a good solution.

On Sat, 10 Aug 2024 at 14:37, Roland @.***> wrote:

I believe this is only an issue with the Vaul library (used by the Drawer component). Vaul injects inline scripts and styles. I think that nonces should not be used in production.

To solve this I simply stopped using that component.

If you use vite when working with shadcn, you can enable nonces specifically in dev mode which fixes CSP issues there.

— Reply to this email directly, view it on GitHub https://github.com/shadcn-ui/ui/issues/2891#issuecomment-2279176490, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAANW3CBHVFEC6DGTTDNADDZQWKH7AVCNFSM6AAAAABEDGWUWGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDENZZGE3TMNBZGA . You are receiving this because you commented.Message ID: @.***>

devnull avatar Aug 10 '24 06:08 devnull

It isn’t an issue with just the Vaul library. I think this is actually an issue with multiple components part of radix. Dialog, Select, Command, Drawer, and probably others but I didn’t check any more.

Yes, you're right. It looks like they inject a script to remove the scrollbar. From my testing, the dialog component still works ok even with this error.

I reported it here: https://github.com/radix-ui/primitives/issues/3063

rolznz avatar Aug 10 '24 08:08 rolznz

It isn’t an issue with just the Vaul library. I think this is actually an

issue with multiple components part of radix. Dialog, Select, Command,

Drawer, and probably others but I didn’t check any more.

Yes, you're right. It looks like they inject a script to remove the scrollbar. From my testing, the dialog component still works ok even with this error.

I reported it here: https://github.com/radix-ui/primitives/issues/3063

Great stuff!

wiesty avatar Aug 10 '24 08:08 wiesty