JedWatson / JedWatson/react-select

Prop for setting Content Security Policy (CSP) nonce value for inline styles used by react-select components

Open
#4,631 4 comments 17 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
28k
Forks
4.1k
PR merge metrics
No merged PRs in 30d

Description

What's your use case?

I have used react-select (version 4.3.0) to implement some reusable select menu components. Upon introducing CSP for inline styles using a nonce value, the styles for the react-select component do not apply since it uses @emotion/react to generate inline styles and there is no way to pass the nonce to emotion via react-select itself. It would be nice to have some CSP support for a future release of react-select

What interface do you have in mind?

After reading through the documentation for @emotion/cache, I was able to pass the nonce value to emotion and was able to resolve the issue of styles not being applied to the react-select component(s) due to the CSP put in place.

import createCache from '@emotion/cache';
import { CacheProvider } from '@emotion/react';
import ReactSelect from 'react-select';

const cache = createCache({
  key: 'jss-class-prefix-key',
  nonce: document.querySelector('meta[property="csp-nonce"]')?.content || '',
});

export default function ComponentUsingReactSelect(props) {
  // Component Logic
  // ...
  // ...
  return (
    <CacheProvider value={cache}>
      <ReactSelect
        style={{
          // Custom styles here
          // ...
        }}
      />
    </CacheProvider>
  );
};

This works great as a temporary solution but comes with a few problems:

  • If future versions of react-select use a different version of @emotion/react and @emotion/cache, this solution might not work
  • If future versions of react-select drop @emotion/core, this solution will not work
  • If future versions of @emotion/react and/or @emotion/cache change the API to pass the nonce value, this solution will not work

It would be nice to have the CacheProvider built into the ReactSelect component and then pass in the nonce value via a prop nonce. E.g.

const nonceValue = document.querySelector('meta[property="csp-nonce"]')?.content || ''; // Or any other way to get the nonce value from the DOM
<ReactSelect nonce={nonceValue} styles={{....}} />

I also use Material-UI in my react application, which also generates A LOT of inline styles. I'm not sure about the implementation details, but they provide the ability to implement CSP with nonce in Material UI. My temporary solution above is based on using the nonce as outlined in the Material UI docs.

This would definitely be a great addition to the many features that react-select provides and reduce the surface for any pre-existing XSS security vulnerability within react-select. Moreover, it would provide an easy transition for developers who are starting to implement a stricter CSP in their application and already leverage react-select in their codebase.

I'm open to any sort of implementation and could possibly try to open a PR as a proof-of-concept if the maintainers think this is something they want to add on the roadmap set for react-select.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by tracing how react-select uses @emotion/react to generate styles, then compare that integration with the @emotion/cache and CacheProvider example in the issue. Define what the proposed nonce prop should control and verify that styles generated by ReactSelect work under a nonce-based CSP; the issue does not name specific files or tests.

Written by the indexing model from the issue text.

Assessment

Tech stack
react, typescript
Domain
frontend, security
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
28/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.