react-select: [V2] Request/Bug: Needs CSP Considerations

We use a pretty strict CSP which doesn’t allow unsafe-inline for style-src. Therefore, when we try to use react-select we get the following errors (and an un-styled react-select component):

Refused to apply inline style because it violates the following Content Security Policy directive: "style-src 'self' Note that 'unsafe-inline' is ignored if either a hash or nonce value is present in the source list.

Unfortunately this is blocking us from using this wonderful component!

I noticed this old issue: https://github.com/JedWatson/react-select/issues/2030, but the props autosize and inputProps have been removed in v2.

EDIT: It looks maybe the best way to add support for this is by using create-emotion which includes the ability to use a single <style> tag with a nonce attribute?

About this issue

  • Original URL
  • State: open
  • Created 6 years ago
  • Reactions: 20
  • Comments: 18

Commits related to this issue

Most upvoted comments

Hi! My concerns were:

  1. That unless the messaging was clear, it would be easy for users to think #3260 was the correct solution even when using static hard coded CSP headers (and not realise doing so would be a security issue) ie: footgun potential.
  2. That by closing this issue it might suggest it was resolved, when really what some of us would like is for emotion support to be optional, and to have a way to disable inline styles entirely.

Hi, Im using Creatable in a project, and its not clear to me how to set/pass a nonce to react-select. Is there any documentation regarding this? Or maybe its possible to disable injecting CSS?

A solution on how to provide a nonce to react-select has already been mentioned in a newer issue https://github.com/JedWatson/react-select/issues/4631#issuecomment-999483078.

To provide a nonce you must use CacheProvider and createCache from emotion (the CSS-in-JS library used). It is recommended to place the CacheProvider at the root of your application, to cover every instance of the Select component available.

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

const cache = createCache({
  key: 'my-cache-key',
  nonce: THE_NONCE    // <----
});

const App = () => {
  // ...
  return (<CacheProvider value={cache}>
    {/* ... */}
  </CacheProvider>);
}

Yep, emotion does have support for CSP nonces, but react-select will have to surface that option to be passed to emotion.

I’m also looking for updates on this issue aged of 3 years and a half.

Took a little time yesterday to try and circumvent. Solved the inputProps issue (getting injectStyles={false} onto the AutosizeInput via “replacing” the component, with no visual change.

/* Some sample code to demonstrate */

// @flow
import * as React from 'react';
import Select, { components } from 'react-select';

const Input = props => {
  return <components.Input {...props} injectStyles={false} />;
};

class MySelect extends React.Component<Props> {
  render() {
    const { onChange } = this.props;
    
    return (
      <Select
        ref={ref => (this.select = ref)}
        autoFocus
        components={{ Input }}
        onChange={onChange}
      />
    );
  }
}

export default MySelect;

Verifying with a Jest Snapshot…(a lot of stuff deleted for simplicity)

                    <Input
                      aria-autocomplete="list"
                      autoCapitalize="none"
                      autoComplete="off"
                      autoCorrect="off"
                      cx={[Function]}
                      getStyles={[Function]}
                      id="org-select-input"
                      injectStyles={false}
                      innerRef={[Function]}
                      isDisabled={false}
                      isHidden={false}
                      onBlur={[Function]}
                      onChange={[Function]}
                      onFocus={[Function]}
                      spellCheck="false"
                      tabIndex="0"
                      type="text"
                      value=""
                    >
                      <div
                        className="css-rsyb7x"
                      >
                        <AutosizeInput
                          aria-autocomplete="list"
                          autoCapitalize="none"
                          autoComplete="off"
                          autoCorrect="off"
                          className=""
                          disabled={false}
                          id="org-select-input"
/* It's provided here */
                          injectStyles={false}
                          inputRef={[Function]}
                          inputStyle={
                            Object {
                              "background": 0,
                              "border": 0,
                              "color": "inherit",
                              "fontSize": "inherit",
                              "opacity": 1,
                              "outline": 0,
                              "padding": 0,
                            }
                          }
                          minWidth={1}
                          onBlur={[Function]}
                          onChange={[Function]}
                          onFocus={[Function]}
                          spellCheck="false"
                          tabIndex="0"
                          type="text"
                          value=""
                        >
                          /* Removing for brevity */
                        </AutosizeInput>
                      </div>
                    </Input>

However, that was not enough as you mentioned (my csp prevents unsafe-inline as well. There’s still a <style data-emotion></style> tag injected in the <head>).