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

Created on 9 Aug 2018  路  11Comments  路  Source: JedWatson/react-select

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?

issubug-unconfirmed issuhas-pr issureviewed

Most helpful comment

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.

All 11 comments

Is the original issue #2030 the only CSP issue now? This is also a blocker for using react-select. Going to try and get v1 to work now as a workaround

@kristiehowboutdat this is also related https://github.com/JedWatson/react-select/issues/2167 but unfortunately is also referencing v1...

I had a brief look at the v2 source code and it looks as though it will need an update in order to work with strict CSPs. Might have some free time to dig into it a bit more in the near future unless someone beats me to it! 馃

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>).

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

I also have the same problem that its blocked by the CSP policy. @icd2k3 did you found a way to allow it now? cause it is indeed a wonderfull component but we cant use it either

Hi! Thank you for looking into this - however I don't think the solution in #3260 helps in the majority of cases?

The CSS spec says (source):

For each request, the server generates a unique value at random, and includes it in the Content-Security-Policy header

Which is emphasised in Google's CSP Guide:

Remember that nonces must be regenerated for every page request and they must be unguessable.

ie: Adding CSS nonce support to react-select:

  • does not help when serving static assets, since the same nonce value would have to be hardcoded in each response, thereby negating the protection provided by CSP.
  • encourages users to use such a solution, which is a security risk

Please can this issue be reopened?

@icd2k3 and anyone else relying on nonce support in selects. I'm re-opening this issue as I've just released 2.3.0 that reverts the following PR #3260. Please see #3346 for the reasoning behind this reversion.

If nonce support is critical for your app, please pin react-select at 2.2.0 until further notice. Nonce support will be reintroduced in 3.0.0 under the following PR #3321 , on release I'll ping this issue once more.

@edmorley, how the nonce is provided to both the react environment and the header of the statically served asset seems like a separate concern to providing that value to react-select (and thus emotion). So I'm as of yet unsure as to how #3260 directly conflicts with the use-case you've provided.

But if it is indeed not the correct solution what would be the alternative, I want to make sure that our provision of nonce to emotion through react-select makes sense, and works for everyone.

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.

in the end what was resolution for this? did you find any workaround ?

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?

Was this page helpful?
0 / 5 - 0 ratings