Content Security Policy in ReactJS app on Heroku - reactjs

Now i ran into such a time consuming error. My CSP policy includes errors and i've tried to remove them but all in vain.
Its a reactjs running on Heroku under an expressjs application. So my folder structure is;
ExpressApp
|-client_folder
|-Reactjs-App
I use a react-csp npm-package to set the CSP policy and actually confirmed that its writing the policy on heroku post-build. React-csp tells us to create a csp.json file and mine looks as follows.
{
"prod": {
"default-src": "'self'",
"script-src" : ["'self'"],
"font-src":["'self'", "*" ],
"style-src": [ "'self'", "https://*.googleapis.com", "'unsafe-line'" ],
"connect-src": ["'self'", "*"],
"img-src" : ["'self'", "*"]
}
}
After i upload the app with git push heroku master, and visit the site, i see it loaded without any styles. And when i check the console, i see this snapshot.
I'm using Material-UI in my project plus all its fonts but it can't seem to include everything i need in the CSP policy. I really need help because i've been stuck on this problem for a while now

it's unsafe-inline not unsafe-line

Errors in the console you showed said that you use wrong token 'unsafe-line' in the style-src directive. Change in to 'unsafe-inline'.
Note that single quotes are mandatory for 'self' and 'unsafe-inline'.

Related

default-src Content Security Policy errors showing on failed form submit in React

I have been trying to get rid of a number of CSP errors when I make a form submission but the number keep increasing. I thought I had handled the fav.icon error by directing express to the public folder in the front-end however it is still flagging with the default-src errors. On reading about default-src errors I also found into about a csp.json however when I added this the same errors have been showing. Where can I access the default-src or set this in React? i know fav.icon is the React logo so I am not so concerned about that but it looks really messy in my console and I am not sure if this causes problems elsewhere in my app.
CSP.JSON
{
"dev": {
"default-src": ["'self'"],
"style-src": [
"'self'",
"https://*.google.com"
]
},
"prod": {
"default-src": "'self'", // can be either a string or an array.
"style-src": [
"'self'"
],
"connect-src": [
"'self'",
"https://localhost:5002/"
]
}
}
backend showing express where my fav.icon file is
app.use(express.static('../WebApp/sustainable-scuba-web-app/public/'));
app.get("/favicon.ico", (req, res) => {
res.sendFile(path.resolve(__dirname, "/favicon.ico"));
});
First of all you have to figure out how the policy is delivered to web page.
CSP can be delivered in 2 ways:
with HTTP header, tutorial how to check is here. Pay attantion to Status Code field, because for 403/404/50X error pahes the CSP header can be published by finalhandler middleware.
with the <meta http-equiv='content-security-policy' content='...'> meta tag. You can check it just by reviewing HTML code.
CSP.JSON is related to react-csp package, it publishes CSP via meta tag. Therefore if you already have CSP delivered with HTTP header (see para 1 above), you will add a second CSP, which can't mitigate the first one.
After found how CSP is delivered and what directives it have, you will have a clue where it's published.
If CSP is delivered with HTTP header (from the server side) - it can be either Helmet middleware (90%), express-csp-header package, simple-csp package or Content-security-policy package. Or even native res.set(field [, value]) / res.header(field [, value]) calls.
If CSP is delivered with meta tag, more probability it's specific React packages/plugins like react-csp.
Most of similar cases are related to Helmet middleware, which since version 4 publishes its own default CSP out of a blue.

Access Denied Error from protected routes from react app hosted on AWS Amplify

I have hosted my react app on AWS Amplify. On trying to access a protected route of the application I am getting the following error on screen
This XML file does not appear to have any style information associated with it. The document tree is shown below.
<Error>
<Code>AccessDenied</Code>
<Message>Access Denied</Message>
<RequestId>3C8377104116CA48</RequestId>
<HostId>nL3bDs+kXEWE8uBFPTLkFLpRg6CCmKfejftWs5wmTWYO6K6WDzpwsDXJCFTK0EFhjJdaHECfuos=</HostId>
</Error>
How do I resolve this?
I found a solution myself from one of AWS forum where a user was kind to share the solution he got from AWS support. I guess AWS does not want the world to know the solutions to the problems it creates so as to sell the support package. Anyway, here is the solution:
In AWS Amplify console in 'Rewrites and Redirects' section add this record
Source Address: </^((?!\.(css|gif|ico|jpg|js|png|txt|svg|woff|ttf)$).)*$/>
Target: /index.html
Type: 200 (Rewrite)
That is it. It magically gets resolved. I don't know why this has to be done or what went wrong in the first place, but taking this action resolves it.
Vinit Khandelwal answer is correct but if anyone is looking for the documentation regarding this issue, here it is. It's a simple configuration add in the Amplify console. Works like a charm!
https://docs.aws.amazon.com/amplify/latest/userguide/redirects.html#redirects-for-single-page-web-apps-spa
When you create a project through the amplify console it automatically creates rewrite rules. When you create a project from the CLI it does not create rewrite rules.
You can copy the re-write rules Amplify uses on a project created from the console to the rewrite rules for your project.
I've included the rewrite rules below.
[
{
"source": "/<*>",
"target": "/index.html",
"status": "404-200",
"condition": null
},
{
"source": "</^[^.]+$|\\.(?!(css|gif|ico|jpg|js|png|txt|svg|woff|ttf|map|json)$)([^.]+$)/>",
"target": "/index.html",
"status": "200",
"condition": null
}
]

Firebase deploy --only hosting does not update React.js webapp content unless site data is cleared

I'm trying to update a react.js site that has been deployed to firebase. The updated content cannot be accessed without using an incognito window or using Dev Tools > Application > Clear Storage > Clear Site Data.
I'm sure this is a problem more strongly related to Firebase Hosting than React, but there seems to be potential interference between React's service-worker.js file and Firebase. Therefore, I have tagged React for completeness.
React Version: 16.8.6
Firebase CLI Version: 7.1.0
My steps are:
change code
$ npm run build
$ firebase serve --only hosting || firebase deploy --only hosting
visit .web.app or localhost:5000
Expectation: I will see the site with the new changes
Reality: I see the old site, without the new changes
Research and attempted solutions:
Setting the Cache-Control Headers
I have tried setting the Cache-Control headers to "no-cache" for service-worker.js in my firebase.json file.
{"source": "/service-worker.js", "headers": [{"key": "Cache-Control", "value": "no-cache"}]},
This is clearly mentioned in the Create React App deployment documentation here:
https://facebook.github.io/create-react-app/docs/deployment
And in numerous Stack Overflow questions, such as the one here:
Firebase hosting - force browser to reset cache on new deploys?
Unfortunately, the problem persists, even when my firebase.json file is as shown below. This has led me to believe that there may be a new, more recent issue.
Fiddling with the Service Worker:
I have also done research around the service worker itself. It is currently set to 'unregister', but I have set it to 'register' and deployed multiple times with no noticeable change.
I am unsure whether it must be set to 'register', given the advice in #1 above.
****firebase.json****
{
"hosting": {
"public": "build",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
],
"headers": [
{"source": "/service-worker.js", "headers": [{"key": "Cache-Control", "value": "no-cache"}]}
]
}
}
****/src/index.js****
.....
const store = configureStore();
....
serviceWorker.unregister();
****directory structure****
/
firebase.json
firebase.src
build/
/static
service-worker.js
index.html
....
....
In the end neither Reactjs nor Firebase Hosting was the source of the problem. I'm just posting this incase someone is in a similar situation and doubts the configuration above, its the correct one, use it.
Redux-Persist's Persist Gate was not working as expected, causing the app to have mini-crashes every time it was redeployed. The crashes occurred before things like the version number could be updated, making the site look like it hadn't received the update.
Clearing the cache would solve the Redux-Persist problem, as it clears the data in the local storage, but this made me think it was a browser cache issue when it wasn't.
If you're using Redux-Persist & Persist Gate and seeing a very similar issue, take a good look at whether Persist Gate is allowing components to render before rehydration. I solved it by using the _persist object in Redux as a flag
In case someone has the issue. I resolve it by removing the .firebase folder at my root folder and add it to my .gitignore.
It keep in cache the previously build version for making deployment faster.
I got some trouble with multi-sites configuration.

Firebase deployment (react app) - generates a blank screen

I am trying to deploy my react app to Firebase (using firebase-tools).
The app was generated using this generator (which has deployment instructions in the readme). I followed them, but they didn't flag that Firebase overrides the index html, so they initial step replaced my html in the build file with the Firebase override. I copied my src/index.html back to the build file and re-ran the init, build and deploy calls.
I have an intercom script on the home page - the only part of the page that renders is the intercom icon. The rest of the page is blank.
I have seen this post. Like this user, I had to remove the predeploy script from my firebase.json because it was generating eslint errors.
The facebook create-react-app advice for Firebase hosting is to add an additional script to the firebase.json with:
"headers": [
{"source": "/service-worker.js", "headers": [{"key": "Cache-Control", "value": "no-cache"}]}
],
I also tried this, but it doesn't change anything.
I tried removing, reinstalling npm and then cleaning the cache (in the functions folder). I have noticed that reinstalling node modules does not result in a functions/node_modules/eslint folder. I'm not sure why.
Others have suggested chrome/devtools/application/clear storage/clear site data. I have tried it but nothing changes.
Some posts attribute the problem to firebase-tools - although more recent posts suggest that the error that gave rise to that solution has now been remedied.
Has anyone found a solution for this problem?
In firebase.json - change public from 'build' to 'dist'
"hosting": {
"public": "dist",

Angular.js application does not work on IIS but there's no errors in the console

I'm trying to push my Angular.js SPA to an IIS7 server but having issues. The application appears to load halfway (as my views and templates are loaded fine), but then stops functioning like so:
As you can see there is no errors in the console...and just for good measure I checked Fiddler which also is having no problems:
The SPA works completely fine on my local web server and only seems to have issues when pushed to IIS. Any thoughts would be greatly appreciated!
EDIT:
Looks like the problem was with angular-csp.css not being properly included when running grunt build -- this was resolved by adding the following to my project's bower.json file:
"overrides": {
"angular": {
"main": [
"angular.js",
"angular-csp.css"
]
}
}
Have you checked the Mime Types on your IIS server? If IIS doesn't know about a particular file type it will often just ignore it.
Also check that you have CORS enabled if you are requesting data from a host other than the one you are deploying to.
Finally, check that you have correctly configured IIS to work with HTML5mode (if you have it enabled. See How to: Configure your server to work with html5Mode
Alright after coming at this with a fresh mind it appears you are correct--everything is working proplery--except my ng-show directives.
Obviously this is because angular-csp.css was not included when running "grunt build."
Since it's not in the angular bower.json main section, I needed to add the following to my projects bower.json:
"overrides": { "angular": { "main": ["angular.js", angular-csp.css"] } }
which fixed the problem.

Resources