material-ui icon indicating copy to clipboard operation
material-ui copied to clipboard

[CSP] "style-src" MUITabs and some other component have inline styles not nonced by the CreateEmotionCache

Open Mateo-P opened this issue 1 year ago • 3 comments

Steps to reproduce

Link to live example: https://github.com/Mateo-P/nonce-problem.git

Steps: 1 cp .env.example to .env 2. yarn install 3. yarn run dev 4. open the browser console (firefox is more descriptive in this case)

Current behavior

Screenshot 2024-01-04 at 16 47 39

Screenshot 2024-01-04 at 17 01 40

Expected behavior

not showing the error on console browser.

  • remove inline style as most of the MUI components
  • make it compatible with nonce assignment when creating the EmotionCache

Context

we are using remixjs+MUI and want to add CSP-Headers following these guides: CSP-guide remix-Styling

we added the nonce-value to the cache on CreateEmotionCache.tsx:

it works with most of the components and all sx's but we have found that some components including MUITabs have a default style="" which is not handled by the CSP nonce config followed in the documentation

on MUITabs docs by inspecting the component on the browser the default style="overflow:hidden;margin-bottom:0" is shown.

Your environment

npx @mui/envinfo
System:
    OS: macOS 14.0
  Binaries:
    Node: 18.16.1 - /usr/local/bin/node
    Yarn: 1.22.19 - /opt/homebrew/bin/yarn
    npm: 9.6.6 - /opt/homebrew/bin/npm
  Browsers:
    Chrome: 120.0.6099.129
    Firefox: 
    Safari: 17.0
  npmPackages:
    @emotion/react: 11.11.3 => 11.11.1 
    @emotion/styled: 11.11.0 => 11.11.0 
    @mui/base: 5.0.0-beta.29 => 5.0.0-beta.27 
    @mui/core-downloads-tracker:  5.15.0 
    @mui/material: 5.15.2 => 5.15.0 
    @mui/private-theming:  5.15.0 
    @mui/styled-engine:  5.15.0 
    @mui/system:  5.15.0 
    @mui/types:  7.2.11 
    @mui/utils:  5.15.0 
    @mui/x-data-grid:  6.18.4 
    @mui/x-data-grid-pro: 6.18.6 => 6.18.4 
    @mui/x-license-pro: 6.10.2 => 6.10.2 
    @types/react: 18.2.46 => 18.2.45 
    react: 18.2.0 => 18.2.0 
    react-dom: 18.2.0 => 18.2.0 
    typescript: 5.3.3 => 5.3.3

Search keywords: nonce csp inline styles MUITabs style="overflow:hidden;margin-bottom:0"

Mateo-P avatar Jan 04 '24 21:01 Mateo-P

i was wondering if there are any updates on this. 🤠 @mnajdova

Mateo-P avatar Jan 10 '24 18:01 Mateo-P

we added the nonce-value to the cache on CreateEmotionCache.tsx:

it works with most of the components and all sx's but we have found that some components including MUITabs have a default style="" which is not handled by the CSP nonce config followed in the documentation

Does this mean that https://github.com/mui/material-ui/issues/38965 is resolved?

Some components just need to have an inline style, for e.g. Slider, Tabs etc. Have you tried using CSPunsafe-hashes keyword to our style-src directive, or unsafe-inline - resource: https://content-security-policy.com/examples/allow-inline-style/

mnajdova avatar Jan 31 '24 09:01 mnajdova

I'm wondering how come instead of any place where there is a style attribute being set it is not simply replaced by a first-child style element so a nonce can be applied from the emotion cache and we don't have a strict CSP breaking it. There is a tutorial here, but it doesn't work for all components https://mui.com/material-ui/guides/content-security-policy/#how-does-one-implement-csp

mjulstein avatar Oct 15 '24 07:10 mjulstein

I use Nextjs and pass a nonce to MUI serverside like so: <AppRouterCacheProvider options={{ nonce: nonce, prepend: true, }}>...</AppRouterCacheProvider>

I am seeing inline-styles blocked by CSP in multiple components:

  • Accordion (min-height:0px, --Paper-shadow: ...)
  • Tabs (overflow:hidden;margin-bottom:0)
  • Paper (--Paper-shadow:none, --Paper-shadow: ...)

As it stands, I can either

  1. Allow unsafe inline styles, or
  2. Generate a bunch of hashes for all these inline styles, which is very cumbersome if they were to change suddenly.

majoer avatar Nov 23 '24 12:11 majoer

@majoer I haven't been able to fix the Tabs one yet. But for the Paper and Accordion I've found a very hacky workaround: I've created a theme in which I override the default style prop of the Paper component:

{
  ...,
  components: {
    ...,
    MuiPaper: {
      defaultProps: {
        style: {
          "--Paper-shadow": "",
        }
      }
    }
  }
}

Tim62556 avatar Nov 25 '24 08:11 Tim62556

The CSP guide (https://mui.com/material-ui/guides/content-security-policy/) is a bit misleading, as it suggests you can enable the CSP style-src directive to work with MUI using nonces, but in reality it only resolves Emotion's generated <style> tags. MUI still uses inline component-level CSS variables for runtime-calculated values (like Paper’s shadow), so those remain a CSP problem unless you remove/override them (which has trade-offs). I wasted a lot of time trying to get style-src to work with nonces, only to find out about the inline styles. It would be good if the documentation reflected this reality.

gidztech avatar Dec 02 '25 14:12 gidztech

Button also has an inline style if you use loading prop; link to the culprit in the repo

Neither hashes nor unsafe-inline is an actual solution, so I'm about to stop using loading prop and instead implement the behaviour myself. It's a shame, I liked it a lot :(

Iorweth333 avatar Dec 02 '25 17:12 Iorweth333