I would like to implement a more secure Content Security Policy (CSP) in my React application. I have utilized the following libraries in my application:
{
"dependencies": {
"@beam-australia/react-env": "^3.0.8",
"@fortawesome/fontawesome-free": "^5.13.1",
"@hookform/error-message": "^0.0.3",
"@popperjs/core": "^2.5.2",
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.3.2",
"@testing-library/user-event": "^7.1.2",
"@turf/turf": "^6.5.0",
"axios": "^0.19.2",
"axios-retry": "^3.1.9",
"body-scroll-lock": "^3.1.5",
"classnames": "^2.2.6",
"d3": "^6.1.1",
"date-fns": "^2.15.0",
"eslint-config-prettier": "^6.11.0",
"file-saver": "^2.0.5",
"framer-motion": "^1.11.1",
"helmet-csp": "^3.4.0",
"jszip": "^3.10.0",
"jszip-utils": "^0.1.0",
"leaflet": "^1.7.1",
"leaflet-draw": "^1.0.4",
"lodash": "^4.17.19",
"mobx": "^5.15.4",
"mobx-react": "^6.2.2",
"phoenix": "^1.5.4",
"query-string": "^6.13.1",
"react": "^16.13.1",
"react-color": "^2.19.3",
"react-day-picker": "^7.4.8",
"react-device-detect": "^1.17.0",
"react-dom": "^16.13.1",
"react-dropzone": "^11.3.2",
"react-hook-form": "6.15.6",
"react-json-view": "^1.21.3",
"react-lazyload": "^3.2.0",
"react-leaflet": "^2.7.0",
"react-leaflet-draw": "^0.19.0",
"react-popper": "^2.2.3",
"react-popper-tooltip": "^3.1.0",
"react-router-dom": "^5.2.0",
"react-scripts": "3.4.1",
"react-select": "^3.1.0",
"react-sortable-hoc": "^1.11.0",
"react-sortablejs": "^2.1.0",
"react-table": "^7.2.2",
"react-time-picker": "^4.0.1",
"serve": "^11.3.2",
"shortid": "^2.2.15",
"sortablejs": "^1.13.0",
"styled-components": "^5.1.1"
},
"devDependencies": {
"concurrently": "^5.2.0",
"eslint-plugin-prettier": "^3.1.4",
"eslint-plugin-react-hooks": "^4.0.8",
"eslint-plugin-sort-imports-es6-autofix": "^0.5.0",
"eslint-plugin-tailwind": "^0.2.0",
"gulp": "^4.0.2",
"gulp-postcss": "^8.0.0",
"gulp-rename": "^2.0.0",
"husky": "^4.2.5",
"lint-staged": "^10.2.11",
"postcss-import": "^12.0.1",
"postcss-nested": "^4.2.3",
"prettier": "^2.0.5",
"tailwindcss": "1.4.6"
},
}
I applied below csp restriction using helmet
directives: {
defaultSrc: ["'self'"],
scriptSrc: ["'self'", "'unsafe-inline'", "'unsafe-eval'"],
connectSrc: ["'self'"],
imgSrc: ["'self'"],
styleSrc: ["'self'", "'unsafe-inline'"],
frameAncestors: ["'self'"],
formAction: ["'self'"]
}
I remove "unsafe-eval" from scriptSrc. However, when I attempted to remove "unsafe-eval," I encountered the following error. [Updated] I got some clue of below issue on here https://github.com/Turfjs/turf/issues/261
Uncaught EvalError: Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "script-src 'self' 'unsafe-inline'".
at new Function (<anonymous>)
at i (turf.min.js:43:13355)
at turf.min.js:43:13417
at Bt (turf.min.js:43:5509)
at turf.min.js:43:12336
at Object.<anonymous> (turf.min.js:1:69)
at Object.<anonymous> (2.4de531c1.chunk.js:2:1027584)
at l (bootstrap:79:22)
at 659 (main.c028a1fc.chunk.js:1:353591)
at l (bootstrap:79:22)
i @ turf.min.js:43
(anonymous) @ turf.min.js:43
Bt @ turf.min.js:43
(anonymous) @ turf.min.js:43
(anonymous) @ turf.min.js:1
(anonymous) @ 2.4de531c1.chunk.js:2
l @ bootstrap:79
659 @ main.c028a1fc.chunk.js:1
l @ bootstrap:79
426 @ main.c028a1fc.chunk.js:1
l @ bootstrap:79
t @ bootstrap:45
r @ bootstrap:32
(anonymous) @ main.c028a1fc.chunk.js:1
Show 5 more frames
Show less
When I remove 'unsafe-inline' from scriptSrc: ["'self'", "'unsafe-eval'"], everything works correctly. However, when I remove 'unsafe-inline' from styleSrc: ["'self'], I encounter the following error.
Refused to apply inline style because it violates the following Content Security Policy directive: "style-src 'self'". Either the 'unsafe-inline' keyword, a hash ('sha256-47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU='), or a nonce ('nonce-...') is required to enable inline execution.
j @ constants.js:4
t @ constants.js:4
e.getTag @ Sheet.js:44
e.insertRules @ Sheet.js:79
t.generateAndInjectStyles @ isStaticRules.js:6
(anonymous) @ Keyframes.js:20
(anonymous) @ Keyframes.js:20
S @ Keyframes.js:20
Xo @ react-dom.production.min.js:153
ka @ react-dom.production.min.js:173
vs @ react-dom.production.min.js:265
lu @ react-dom.production.min.js:246
su @ react-dom.production.min.js:246
Js @ react-dom.production.min.js:239
(anonymous) @ react-dom.production.min.js:123
e.unstable_runWithPriority @ scheduler.production.min.js:19
Vi @ react-dom.production.min.js:122
qi @ react-dom.production.min.js:123
Wi @ react-dom.production.min.js:122
vu @ react-dom.production.min.js:257
e.unstable_runWithPriority @ scheduler.production.min.js:19
Vi @ react-dom.production.min.js:122
gu @ react-dom.production.min.js:257
(anonymous) @ react-dom.production.min.js:256
B @ scheduler.production.min.js:17
x.port1.onmessage @ scheduler.production.min.js:14
Show 18 more frames
Show less
I also tried using INLINE_RUNTIME_CHUNK=false like this below also no help. "build": "npm run build:css && INLINE_RUNTIME_CHUNK=false react-scripts build"
I was able to fix the issue with inline styles used in my application. However, I noticed that some libraries are using inline style syntax, and now I am somewhat lost with no idea how to address these.