I've built a single-page app with React.js and hosted it on AWS behind a Cognito login page (see this blog post and this Lambda template). This triggered errors that complained about the lack of a content security policy, so I added the csp-html-webpack-plugin to my standard create-react-app setup using react-app-rewired.
config-overrides.js
const { override } = require("customize-cra");
const cspHtmlWebpackPlugin = require("csp-html-webpack-plugin");
const cspConfigPolicy = {
"default-src": "'none'",
"base-uri": "'self'",
"object-src": "'none'",
"script-src": ["'self'"],
"style-src": ["'self'"],
"img-src": ["'self'"],
"frame-src": ["https://drive.google.com/"],
"manifest-src": ["'self'"],
};
function addCspHtmlWebpackPlugin(config) {
if (process.env.NODE_ENV === "production") {
config.plugins.push(new cspHtmlWebpackPlugin(cspConfigPolicy));
}
return config;
}
module.exports = {
webpack: override(addCspHtmlWebpackPlugin),
};
.env
INLINE_RUNTIME_CHUNK=false
This results in a /build/index.html file with a Content-Security-Policy meta tag and without any inline JavaScript or CSS, but it still didn't work perfectly. There were still lots of errors about inline styles (presumably CSS being injected by React components). I was able to bypass those by manually removing the nonce that followed style-src 'self' and replacing it with 'unsafe-inline';. This isn't ideal, but I think it's acceptable for my app.
<meta
http-equiv="Content-Security-Policy"
content="base-uri 'self'; object-src 'none'; script-src 'self' 'nonce-4vMiP/MSTpSmzZRvWpahlQ==' 'nonce-ttbsbXQ2ka2E/pUj4y8w0g==' 'nonce-SPF0ZOWgqYX6X7cGjFBdNQ=='; style-src 'self' 'unsafe-inline'; default-src 'none'; img-src 'self'; frame-src https://drive.google.com; manifest-src 'self';"
/>
The bigger problem is that, even though policies for frame-src and manifest-src are set in the meta tag, the browser doesn't seem to be reading them. It still outputs the following errors and refuses to display cross-domain content in iframes.
Refused to frame 'https://drive.google.com/' because it violates the following Content Security Policy directive: "default-src 'none'". Note that 'frame-src' was not explicitly set, so 'default-src' is used as a fallback.
Refused to load manifest from 'https://mysubdomain.cloudfront.net/manifest.json' because it violates the following Content Security Policy directive: "default-src 'none'". Note that 'manifest-src' was not explicitly set, so 'default-src' is used as a fallback.
All the other content is loading correctly now. The errors don't appear when I run the app locally or host it without Cognito authorization.
Any ideas on how to fix this?