JedWatson / JedWatson/react-select
Prop for setting Content Security Policy (CSP) nonce value for inline styles used by react-select components
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-selectuse a different version of@emotion/reactand@emotion/cache, this solution might not work - If future versions of
react-selectdrop@emotion/core, this solution will not work - If future versions of
@emotion/reactand/or@emotion/cachechange 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
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- 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