Netlify/Create React App secret api keys exposed in build - reactjs

Building create-react-app (v2) on Netlify hosting and need to deal with secret keys for payment processing and content pulls from CMS (Contentful).
CRA is exposing secret keys in the build output using 'process.env.REACT_APP" and CRA over writes the space and doesn't allow these keys to be hosted in the variable space and access at build time securely.
Is there best practice on the right type of approach to keep the keys secure?

You have two different cases here. Speaking about Contentful you're probably using the CDA. This API is read-only and has its own tokens. There is no harm by exposing it to the public and your react application with REACT_APP_.
A payment provider is a different story though. For this I'd recommend to using Netlify functions to not expose the token. This way your react application can use the function endpoint and your token stays safe. :)

Related

Secure webapp with Django and React

I'm experimenting with these 2 technologies to make a secure web app [Currently learning React (60%) and Django (<50%). This is intended to be like a medical database, so doctors and nurses enters their patients' information. They need to login obviously. I wanted to implement React-based UI (And not using the classic method to create views from django), so I've found many tutorials just like this one:
https://www.digitalocean.com/community/tutorials/build-a-to-do-application-using-django-and-react
It basically turns Django into a restAPI, and then the React frontend uses axios to retrieve data from the endpoint. Sounds not bad at all (comparing to the native method of rendering data in a webpage from Django), but the problem is that I have no idea on how to make this secure, you know, Django provides an auth system, which is pretty good and secure, I have to say, but in a project with this structure, the auth needs to be done in React, so there many questions appear:
To start with, is it a good idea to make a project of this structure? (If no, then what could be a good one)
If it's a yes, how can I protect the API so only logged in users can interact with it? (What mechanisms to ensure protection)
Yes, this is absolutely a good idea to separate the client application and the backend server application.
You can access the backend through the rest api basically with any frontend framework/app/script.
Customers are able to extend their own applications with the abilities of your backend service.
You can create multiple different frontends that use the same backend or different parts of the same backend via the rest api (multi-branding, reselling). Or you can just swap the frontend framework every second year to a new one.
It's also easier to create different automations by using the rest api.
And the list goes on.
For django rest api auth I would recommend Token Authentication which is already included in the Django REST Framework and for React use this tutorial for implementing the login and the token handling.
And don't forget to use TLS on your servers, and create API documentation. (Example)

Is there a way to dynamically inject sensitive environment variables into a serverless React frontend application using Azure/Github Actions?

I'm sort of restricted to Azure since that is what the client is already using.
But basically, we have this React website which is your typical react-scripts no server website, which means that there's nowhere in Azure Static Webapps to set environment variables for a frontend application.
I saw this on Azure Static Webapps Configuration, but subject to the following restrictions, won't work for my use case because there is no backend API for my frontend application - the backend associated with the frontend is published separately to Azure App services. And I need the secrets on the frontend to use some npm packages that require them, which I would prefer to do on frontend instead of backend.
Are available as environment variables to the backend API of a static web app
Can be used to store secrets used in authentication configuration
Are encrypted at rest
Are copied to staging and production environments
May only be alphanumeric characters, ., and _
I was doing some more research, and this seems to sort of be up the alley of what I'm looking for:
https://learn.microsoft.com/en-us/answers/questions/249842/inject-environment-variables-from-pipeline-to-azur.html
Essentially, I really want to avoid hardcoding secrets into the React code because that's bad practice.
I personally see a few different (potential) options:
Create an endpoint on the backend Spring Boot api that simply serves all environment variables
This is the most trivial to implement but I have concerns about security with this approach. As my frontend has no access to any kind of secrets, there's no way for it to pass a secure token to the backend or anything to authenticate the request, so someone could conceivably have chrome network inspect element tab open, see that I'm making a request to /getEnvironmentVariables, and recreate the request. The only way I can see to prevent this is to have IP restrictions enacted on the backend API, so it only accepts incoming requests from the IP address of my frontend website, but honestly that just sounds like so much overhead to worry about. Especially because we're building the product as more of a POC, so we don't have access to their production environments and can't just test it like that.
Have the Azure Static Webapps Github Actions workflow somehow inject environment variables
So I've actually done something similar with GCP before. In order to login to a GCP service account to deploy the app during continuous build, the workaround was to encode a publicly viewable file that could be freely uploaded to whatever public repo, which could only (realistically) be decrypted using secrets set on the CI/CD pipeline, which would be travis-ci, or in my case, Github Actions. And I know how to set secrets on Github Actions but I'm not sure how realistic a solution like that would be for my use case because decrypting a file is not enough, it has to be formatted or rewritten in such a way that React is able to read it, and I know React is a nightmare working with fs and whatnot, so I'm really worried about the viability of going down a path like that. Maybe a more rudimentary approach might be writing some kind of bash script that could run in the github actions, and using the github actions secrets to store the environment variables I want to inject, run a rudimentary file edit on a small React file that is responsible for just disbursing environment variabless, before packaging with npm and deploying to Azure?
TLDR: I have a window in github actions when I have access to a linux environment and any environment variables I want, in which I want to somehow inject into React during ci/cd before deployment.

Next.js monorepo: multiple apps on subdomains vs. one app?

I just started using nx.dev to migrate from a single app repo to a monorepo as I have added a very basic static documentation app to the mix which is deployed to a subdomain docs.company.com.
My main application is currently deployed to main route company.com. However, one could think of it as different apps as well where there is app1, app2 and admin for example. I do like the idea of having everything as a single application as it can be easily deployed with nx and Vercels monorepo support.
I am just not sure what the go to approach is here. Of course, I could split up the main app into multiple apps and deploy them independently to subdomains such as:
admin.company.com
app1.company.com
app2.company.com
If understood correctly, I could also use multi zones support if I do not like subdomains and use one domain instead.
This main app, that could logically be split up in multiple apps is non public and authentication is required. It is completely client side rendered while apollo client is used to interatct with the GraphQL API. This API server also sets an http-only JWT cookie for authentication. I am quite sure I could mitigate the issue with subdomains in this regard by setting the domain cookie setting, such that the cookie is also valid for subdomains.
However, as the cookie is http-only I cannot access it from the client and need to keep track of the logged in status in my global state mangement (which is overmind.js). Splitting up the app would add some extra complexity to persist global state between subdomain apps.
I am not sure whether this is worth it or if it is better sticking to the one app approach. I would love to hear your opinion and maybe I have forgotten some major issues. Some questions that come to my mind:
What are the advantages and disadvantages of using subdomains?
Is it more preferable to use multi zones and only one app?
How could the auth/global state issues be solved if switching to multiple apps?
What are your thoughts?

AWS Serverless: configure multiple frontend apps under one domain

I have two frontend apps. First one uses Static Generation (for SEO purposes), and the Second one uses Client Side Rendering (for all stuff behind auth flow).
I want to have both of them under the same purchased domain, with the base endpoints to be something like:
mydomain.com\public\* : for all my public facing statically generated content using the first App.
mydomain.com\auth\*: for all the stuff that lies behind the auth flow.. made using the second app.
So the question is:
How to map these two separate apps to two base endpoints under the same domain? I was reading this post Share an API Endpoint Between Services, but it seemed to be for the backend.
In case anyone is interested to know why two separate apps:
It's because the Static generation is done using Next.js, while the Client side stuff is done using simple create-react-app. This post explains why this combination needs to be separately deployed.
Refer to this
Create two separate s3 buckets for your NextJs and React app. Attach them to a CloudFront distribution. Attach a lambda function to your CloudFront distribution and route requests to different origin based on whether the request.uri.startsWith('/public') or not.

How to secure third party API keys in firebase hosting?

I am using different third party API keys in my reactjs-firestore project. But I can't find a way to secure them in firebase hosting. How can I hide these API keys in firebase hosting?
For example, in Netlify hosting services they provide environment variables feature which can be used to secure the API keys.
that is I can just store the API keys in the variables in netlify and it will be retrieved from there which will be secured.
But in firebase how do I do this?
I can't seem to find a similar setting wherein I can store the keys as environment variables in the hosting services.
if there is no such feature is there another way to secure these API keys?
and for the firebase API keys,
I have already read some answers and understood that firebase API keys will not be hidden.
is there at least some way to secure these firebase API keys to just one secured URL at least? (I know that writing security rules is the best approach but am trying to find other options as well).
I can't seem to find a way to secure firebase project API key usage to one secured URL.
I have tried to find ways to secure the API key but I haven't been successful.
below is how I retrieve data in reactjs code
axios.post(`https://data.retrieval.com/1/data?key=API_KEY`, data)
I am trying to hide the API_KEY in the production code
I want to secure third party API keys in my hosted website.
and also restrict my firebase project API key to just one secure URL.
am not able to do this now.
any suggestions or solutions?
Thank you for trying to help.
and thank you for your time
If you're using the API key in client-side code, there is always the chance that a malicious user can find the key and abuse it. The only way to protect against this is to not use the API key in client-side code, or to have a backend system that can protect access based on something else (such as Firebase's server-side security rules).
Since your backend system likely doesn't have such a security model, you'll typically have to wrap their API in your own middleware that you host in a trusted environment such a server you control, or Cloud Functions. That's then where you ensure all access to the API is authorized, for example by setting up your own security system.
Not sure if this help, but my Firebase Cloud Function use this.
Create your secret by
firebase functions:config:set secret.API_KEY="THE API KEY"
Access your secret by using functions.config().secret.API_KEY
Note: This should only use for server use case, not in the client code. For server I meant Firebase Cloud Function or your backend.
The safe way I've found to store your third-party keys is using the Google Secrets Manager. It is now baked into the Firebase Functions SDK and works very well. You can find the information here, under the section titled "Store and access sensitive configuration information".
Two things worth mentioning:
There is a small bug in the syntax example, they forgot to add the https before onCall.
You'll need to give the service account which runs the cloud function when deployed access to the secrets. Here are the official docs on how to do that. If you are deploying through Firebase, you'll want to look for the service account whose address is [project-name]#appspot.gserviceaccount.com. If you have any doubts about which service account is running the Cloud Function, look under the Details tab in the Cloud Functions section of Google Cloud Platform and it will show you that information. Also, under the Variables tab, you can see what secrets your Cloud Function has access to.
This process makes it really easy to manage third-party keys as you can manage them at your project level and not have to worry about them being stored else where or needing to manage .env files. It also works with the Firebase Emulators and uses the credentials of the user running the emulators for access.

Resources