secure nodejs production environment that use dotenv - node.js

By using dotenv I can ignore development .env file before pushing it to the git repository, it comply with The Twelve-Factor App config factor. It prevent configuration from exposing to others especially open source project.
But I am stuck when deploying it to the production, either using cloud deployment or using docker.
How can I include this file? Should I save the file into Vault or something?
Please help me to understand how can I secure my deployment environment.

You don't. The server environment (docker or otherwise) needs to be configured with its own environment variables, not the development ones. Any that will be the same in both you configure as default values for the application so that they have that value even if the variable isn't set.

You can use a file transfer protocol such as filezilla or cyberduck and transfer the file to your production server environment. Make sure the .env file you send to your server contains the credentials for the production database and not the development one and so on. You could alternatively just add environment variables to your remote server's .env or .bashrc file, but this is probably not advisable compared to a .env file. As long as no one but you has access to the remote server (docker, heroku, aws, etc) your credentials should be secure. Never share your .pem files.

Related

Using MongoDB and storing critical information so that it is protected

I am using mongoose with MongoDB in a NodeJS application. Right now, in development, I have a configuration (.env) file which stores sensitive information my code needs to run. For example, the MongoDB password & URL, emails & passwords needed to email using the code, etc.
When I put it into production, it would obviously be wrong to upload this configuration file anywhere on the cloud, given the information in it. How can I make it so my production code, hosted somewhere such as Heroku, can access these needed variables without letting undue access to them?
Thanks in advance!
You are right, pushing your env file to production is pretty bad from a security perspective.
The way you would go with storing your environmental variables differs between cloud platforms, but essentially you should get a secure way of adding them through either an user interface or through terminal (You usually find these information easily by looking into your provider documentation).
To store them in a project deployed on Heroku, you will need to:
Log to Heroku
Open the newly deployed project
Head over the Settings tab
Find the section named Config Vars
Click on Reveal Vars
Add your variables in there
And you are good to go!

module.exports vs environment variables

What is the difference between storing sensitive credentials in a credentials.js file as opposed to an .env file?
With module.exports you can write:
const KEY = require("./credentials.js");
Whereas with .env files you can write:
const KEY = process.env.KEY;
In both cases you accomplish the same goal of making some variable "global" and accessing it globally. Why do people use .env and dotenv instead of just using Node's built in module.exports system?
Environment variables are meant to be defined on the machine (system). The environment variables can be used on multiple application running on the same system.
Exported variables are only limited to the application you are running.
In your case: If you want to deploy your application on 3 servers (Dev, QA, Prod) but on with different credentials, it doesn't make sense to change the credentials every time when deployment. Even if you define credentials for every server it has to be static and if you want to change it, you must do changes in file and deploy the app again to reflect the changes. In case of environment variables, you just have to change it on the targeted system and restart the server, so there is no need to deploy the app again.
It becomes a mess to manage when there are changes in more than one environment variables. Also, environment variables are useful when it comes to integration with other services.
For security in environment variables, you can read this
When storing credentials:
There is risk of exposing credentials to version control system when stored in config file
It doesn't matter where credentials are stored, if the system is compromised
You can use a runtime configuration file. Find it here

Can config files in nodejs express be hacked?

I store my secrets (API key, password...) as plain text in my config files, and push it into a private repository in GitLab. It is not a best practice, I know, but I think it's quite hard to read these information.
Unfortunately, some of my secrets are leaked lately. My questions are:
Can config files in nodejs express be hacked? I tried to navigate to config folder in web browser but get the 404 error.
How to secure config files in nodejs? I did a research and found 2 major solutions: to use environment variables and to encrypt/decrypt config files. Using environment variables seems to be easy to implement but in case of having a lot variables, this method is quite inconvenient. Is there any other solution? Which npm package is good for securing config files?
Yes, even Gitlab private repos are not secure. And the solution is to create a .env file in the root directory and put it in git ignore. And share .env file securely though ssh.

Node.js environment Variables VS configuration file

Can someone explain what's benefits of environment variables in Node.js over regular config file?
In my project I have config.js files with DB details, AWS keys, etc. This file is added to .gitignore and never shared on repository, instead there is demo.config.js file with all required parameters filled with fake creditentials, so you can just copy it as config.js and fill it with correct details after fresh install.
This file is "required" in every file when I need credentials in my project and on my development machine this config file is configured with test server details and with actual production server details on production machine.
Lately I read everywhere that everyone should use environment variables to store credentials safely, but I don't see any benefit to doing so in my project.
I'm not saying it's bad and my approach is better, I just want to know what actual benefit (security or otherwise) will I get with environment variables over my setup?
For me it is more like a common standard than anything else. The way how you use config.js is practically the same as using environment variables. But instead of storing the configuration in environment variables, you store it in js file.
The main difference is how you read that config. All mainstream languages I know, will easily allow you to read from environment variables, there is really wide support for it. Reading from config files brings additional complexity as you need to know the structure of that file, how to parse etc. In some languages (maybe node.js) it is probably easy to read from js file, but in others it could be difficult task.
That's why using environment variables is just a common standard and language agnostic. You can even read it in bash scripts etc.
Edit: adding reference to The Twelve-Factor App, the Config section is particularly connected with above question:
https://www.12factor.net/config
One benefits i see when you are using docker for local development and kubernetes or any container orchestration for SIT/UAT etc where config setting is there . In local development we keep all env variable required and move the same on container based system

what's the preferred way to store sensitive settings in web apps?

I know that a good way to store data like db passwords, etc. is via environment variables, but setting environment variables manually for every server instance created is time consuming.
I'm planning to deploy my project to the cloud (using aws ebs or heroku).
where should I store my db password?
I think the .ebextensions file isn't a good option because it's tracked in vcs
Don't ever store secrets in source control. A common practice is to either put them in a secure file or in something like https://www.vaultproject.io/ then inject them (programmatically via a script or some other deployment/configuration tool) into the environment when you bring up your VM (or container or whatever).
My recommendation is to create a properties file which can be stored in the resources folder of your application and the code can access the resources. do not need environment variable. One property file can contain all db's userid and passwords. Deploy job based on url mapping in the properties file. For example, look at a spring hibernate example project which uses a property file. Or look at ant deploy scripts. Hope it helps.

Resources