Describe the bug
The JS.browserOrNode() function uses eval-like expressions that prevent amplify-js from running when a strict Content-Security-Policy is in place. The eval-like expressions I'm talking about are new Function("..."), which are not allowed in a Content-Security-Policy, that doesn't allow eval().
This leads to the following error message in the browser (in this case Firefox):
Content Security Policy: The pageās settings blocked the loading of a resource at eval (ādefault-srcā). vendor.js
This prevents us from using any of the functionality provided by amplify-js. I believe the issue was introduced with commit 52bd2877bee66b934885e6726b68c8a926c28c3d, which changed the functionality in browserOrNode() to use new Function().
To Reproduce
default-src 'self'; (script-src 'self'; should also work), see Sample Code for the one we are using.amplify-js package that uses JS.browserOrNode() (in our case @aws-amplify/auth).Expected behavior
amplify-js (or rather browserOrNode()) should not break any Content-Security-Policy that forbids eval()
Screenshots
Error in Firefox console:

Error in Google Chrome console:

Environment
System:
OS: Linux 5.3 Ubuntu 19.10 (Eoan Ermine)
CPU: (4) x64 Intel(R) Core(TM) i5-6200U CPU @ 2.30GHz
Memory: 141.61 MB / 7.64 GB
Container: Yes
Shell: 5.0.3 - /bin/bash
Binaries:
Node: 12.14.1 - /usr/bin/node
Yarn: 1.21.1 - /usr/bin/yarn
npm: 6.13.4 - /usr/bin/npm
Browsers:
Chrome: 79.0.3945.117
Firefox: 72.0.1
npmPackages:
@aws-amplify/auth: ^2.1.3 => 2.1.3
@babel/core: ^7.8.3 => 7.8.3
@babel/preset-env: ^7.8.3 => 7.8.3
@babel/preset-react: ^7.8.3 => 7.8.3
@testing-library/jest-dom: ^4.2.4 => 4.2.4
@testing-library/react: ^9.4.0 => 9.4.0
@testing-library/react-hooks: ^3.2.1 => 3.2.1
@types/jest: ^24.9.0 => 24.9.0
@types/react: ^16.9.17 => 16.9.17
babel-eslint: ^10.0.3 => 10.0.3
babel-loader: ^8.0.6 => 8.0.6
copy-webpack-plugin: ^5.1.1 => 5.1.1
core-js: ^3.6.4 => 3.6.4
dotenv: ^8.2.0 => 8.2.0
eslint: ^6.8.0 => 6.8.0
eslint-config-airbnb: ^18.0.1 => 18.0.1
eslint-config-jameda: ^1.6.4 => 1.6.4
eslint-config-prettier: ^6.9.0 => 6.9.0
eslint-import-resolver-webpack: ^0.12.1 => 0.12.1
eslint-plugin-import: ^2.20.0 => 2.20.0
eslint-plugin-jest: ^23.6.0 => 23.6.0
eslint-plugin-jsx-a11y: ^6.2.3 => 6.2.3
eslint-plugin-react: ^7.18.0 => 7.18.0
eslint-plugin-react-hooks: ^2.3.0 => 2.3.0
file-loader: ^5.0.2 => 5.0.2
history: ^4.10.1 => 4.10.1
html-webpack-plugin: ^3.2.0 => 3.2.0
husky: ^4.0.10 => 4.0.10
jest: ^24.9.0 => 24.9.0
jest-junit: ^10.0.0 => 10.0.0
jest-styled-components: ^7.0.0 => 7.0.0
lint-staged: ^9.5.0 => 9.5.0
prettier: ^1.19.1 => 1.19.1
prettier-eslint: ^9.0.1 => 9.0.1
prettier-eslint-cli: ^5.0.0 => 5.0.0
prop-types: ^15.7.2 => 15.7.2
qrcode: ^1.4.4 => 1.4.4
qs: ^6.9.1 => 6.9.1
react: ^16.12.0 => 16.12.0
react-dom: ^16.12.0 => 16.12.0
react-test-renderer: ^16.12.0 => 16.12.0
regenerator-runtime: ^0.13.3 => 0.13.3
styled-components: ^5.0.0 => 5.0.0
stylelint: ^13.0.0 => 13.0.0
stylelint-config-recommended: ^3.0.0 => 3.0.0
stylelint-config-styled-components: ^0.1.1 => 0.1.1
stylelint-processor-styled-components: ^1.9.0 => 1.9.0
webpack: ^4.41.5 => 4.41.5
webpack-cli: ^3.3.10 => 3.3.10
webpack-dev-server: ^3.10.1 => 3.10.1
whatwg-fetch: ^3.0.0 => 3.0.0
npmGlobalPackages:
npm: 6.13.4
Additional context
We ran into this issue when we upgraded from @aws-amplify/auth 1.3.3 to 2.1.3. The last version that works is 1.4.3, anything after 1.5.0 is not working.
Sample code
Our Content-Security-Policy:
default-src 'self';
connect-src https://cognito-idp.eu-central-1.amazonaws.com;
object-src 'none';
style-src 'self' 'unsafe-inline';
base-uri 'none';
I hope I didn't forget anything. If there's anything else I can do to make the issue more clear or to provide additional insights, please let me know.
Thanks for the report and the detailed repro steps @MHarutunian
I'll be taking a look and reporting back here
I'm having the same issue. My CSP policy is "script-src 'self' 'unsafe-inline'". I do NOT want to add unsafe-eval to the CSP as it is not recommended (will also lower my Mozilla Observatory score). I am using the Amplify framework mainly for the Logger, Hub, and the i18n. Looks like GoogleOAuth and FacebookOAuth are calling browserOrNode(). I'm using aws-amplify 2.2.0
The master branch has eval: https://github.com/aws-amplify/amplify-js/blob/master/packages/core/src/JS.ts
The version tagged with 1.3.3 is not using eval: https://github.com/aws-amplify/amplify-js/blob/aws-amplify%401.3.3/packages/core/src/JS.ts
I'm having the same problem, is there any workaround here?
Something I don't understand is why are GoogleOAuth.js and FacebookOAuth.js executed? I don't use OAuth at all! š¤
I'm having the same problem, is there any workaround here?
Something I don't understand is why are
GoogleOAuth.jsandFacebookOAuth.jsexecuted? I don't use OAuth at all! š¤
The libs are included bc Amplify includes the relevant libraries for Cognito. Amplify lib is not split into fine grain packages. It's all or nothing. So you may not be using Cognito but auth related code gets pulled in nonetheless.
To avoid future issues of this type, I'd recommend ensuring the following rules are enabled:
Most helpful comment
To avoid future issues of this type, I'd recommend ensuring the following rules are enabled: