How to keep connection strings and API keys secure in PRODUCTION - connection-string

I am about to deploy a .net core application to production ( core 2.2 ). I am aware of user secrets and environment variables to store when still in development. But what are best practices to ENSURE that these passwords and API keys are not exposed in production? And, how safe is it to store these in the appsettings.json on a hosted web server? My app is semi mission critical and it would be a disaster if they leaked out. And lastly are there any open source / paid for code snippets to assist in encrypting these?
Thanks Luke.

It's not safe to store them in the appsettings.json, you may want to consider storing in a Vault if possible (best of these options) or in an environment variable, the registry, or in a file on disk.
Wherever you store it, the sensitive data should not be stored in plaintext, it should always be encrypted. With NET Core you can use Data Protection API (built in so it's free) to encrypt it, or aspnet_regiis.exe. Both of those need to be encrypted and decrypted on the same machine to work.

Related

Hyperspectral image storage

I would like to save hyperspectral images using Python, but I don't know where I can persist the data. I have thought about HDFS. I need to do it on my local server without using cloud providers
Is there a way to make it easy, and do you recommend any particular database?
HDFS generally requires you to build and administer your own Hadoop cluster.
I'd consider cloud object storage such as AWS S3 or Google Cloud Storage for the following reasons:
Relatively cheap
Fully managed
No restriction on file size or number of files
Easy Python APIs
Durable - data can be replicated across multiple regions (all handled automatically for you), so you don't need to worry about losing anything if a server dies.

Should I use local storage in Electron for database config?

I have written an Electron app. It's working fine. I use local storage to save all the options that can be made in the app. That includes database configuration.
In a browser this is may a good idea because a website may be able to hack it?
This is not a website but an Electron app that does not load any webpages except for the main index html file.
Should I use local storage for database config?
So, should I use local storage for database config if I care about basic security? It's not a bank (hash not needed), but it should not be open to the world to get.
Except for the main questions, there are some optional subquestions around it.
If it's not a good idea, what should I use instead?
If it's not a good idea, how could it be hacked when I decide what goes into the html?
Local storage is not a file. Is there a chance the settings may be lost and gone?
I assume following:
You use a two tier architecture. Client written in Electron and a database.
You put credentials to the database into the local storage operated by the Electron app.
The database is storing non-public data, or other data that needs some kind of protection regarding integrity or confidentiality.
The database and the schema are multi-tenant.
If what I claim above is true, then no, your solution is not secure. The solution you provide does not fall into the category of hardcoded secret, but is pretty close. In memory you may hold secrets that may give the user the same level of right he already has, like his session cookies or tokens. You are not allowed to put anything which - when obtained - would allow the user to have bigger access rights.
So, how to solve this. Simply said you can't. You might be tempted to obfuscate or hide or encrypt data, but obfuscation can be broken, hidden can be found and encrypted data must be decrypted with a key at some point that must be lying around somewhere.
Solution is rather a three tier architecture with an application server doing authentication, authorization and access control. Unless you want to play and give every user his own db schema/access rights in the database, which might be a solution too, but I don't know anyone who would be doing this.
As others have noted, you should definitely not put database connection secrets on the client. Secrets only stay secret if you can control its location. Living on a client machine is not a good spot for this and no amount of encryption will save you. Configure an application server with authentication and access control, and have the client communicate through this gate keeper before getting to the data layer.

How to do Redis Data encryption?

We can secure the data while its travelling using spiped or stunnel. But How do we do that while the data at rest? What if someone took the whole database? How can we encrypt the persistent data storage? Do we need to do this in application layer?
When looking at the documentation at https://redis.io/topics/security it is clear that encryption of data at rest isn't supported:
Redis is designed to be accessed by trusted clients inside trusted environments. This means that usually it is not a good idea to expose the Redis instance directly to the internet or, in general, to an environment where untrusted clients can directly access the Redis TCP port or UNIX socket.
And (emphasis mine):
[...] in general, untrusted access to Redis should always be mediated by a layer implementing ACLs, validating user input, and deciding what operations to perform against the Redis instance. In general, Redis is not optimized for maximum security but for maximum performance and simplicity.
What I would do is to set the database im some sort of private server not accesible by the internet. You can comunicate to it through private IP addressed.
Amazon Web Services offers a very good architecture for Virtual Private Cloud that you can try using their free tier. (Use t2.micro Instances and make sure their summed running time doesnt go over 30 days, also that they dont use up more than 30Gb of storage capacity)
With respect to how to protect the data if a hacker could actually access the database: I would encrypt all the sensitive info that I will be checking in the future with a one way hash algorithm. Every programming language has their own syntax for SHA256 and several others encrypting algorithm. I believe for Node.js you could use crypto module (not sure if it has the one way hashing but it should.)
So every time a user sends something, you can hash it and compare it to the database encrypted data.
For example for the case of emails, it could be a two way hashing, that way it can be retrieved afterwards.
At this point, even if some accessed the database it would get irrelevant information.

storing original password text

My web application stores external website login/passwords for interaction with them. To interact with these websites I need to use the original password text, so storing just the hash in my database is not going to work.
How should I store these passwords?
Edit:
I am concerned if someone gets access to my server. If I use some kind of 2-way encryption and they have server access then they can just check how the passwords are decrypted in my backend code.
It seems to me that you want to store passwords in a similar fashion as Firefox and Chrome. So why not look at how they do it?
This is how Chrome does it:
http://www.switchonthecode.com/tutorials/how-google-chrome-stores-passwords
If you MUST do this, you should use a two-way encryption. There are a lot algorithms (ciphers) for this, but basically you encrypt your data with an encryption key, and use the same key for decrypting them again.
Choosing the right cipher depends on which are supported by the programming language of your choice, but examples are:
Blowfish
3DES
Skipjack
They come in different complexity and some are harder to crack than others. You should realize though, that no two-way encryption is safe from cracking, given enough time. So it all depends on, how sensitive these passwords are.
/Carsten
Decide what you are protecting them against. Options include (but are not limited to): Accidental disclosure, disclosure by you, disclosure in transmission, disclosure due to code error, disclosure due to physical theft of hardware, etc.
If this is a web application, and each user is storing his/her own set of passwords, then you might encrypt these passwords with their login password to your application. If this is an application that each user installs separately, and which keeps its own local database, you could have an optional master password (like Firefox does).
If you are just ensuring that the data is safe if the hardware is stolen, you might use a full disk encryption solution like TrueCrypt or PGP WDE, or Ubuntu, Debian, or Fedora's built-in approach, and require a PIN or password on every boot.
If you just care about secure transmission, have code to ensure that you use transport security, and don't worry about encrypting the data in your database.
I would go about this in the following way.
Protect data against hardware being stolen:
Use disc encryption as discussed in previous posts.
Protecting data if server is compromised (hacked):
I would use two different servers for this project, one worker server and one front server.
A) Worker server
This has the DB with passwords etc,
it also connects to other services.
To connect to worker server, users
can do it through an API. API should
have on function, insertUserData,
which allows userdata to be inserted,
API escaped all the input.
API uses
a DB user which only has input
privilegies on the userData table.
This would be the only way to contact
this server.
Only allow SSL
connections.
This server in turn runs chron jobs that connect to external services, pulls data from them and populate it's DB. Use a different DB with different user privileges.
This server runs another chron JOB which connects to the front server and pushes new data to front server.
Minimal amount of services running
Only SSH/SCP from your IP, tight firewalling. Block if connections exced X / min etc as they only would do an occasional insert.
NO FTP etc.
B) Front server
Receives data from Worker server, never uses the passwords itself. Only way to contact worker server is through API mentioned above, only for new user information. This is where all users login to see their information etc.
The problem with doing it all on the same server, if you get hacked the hacker can sit and sniff all incoming data / passwords etc.. so even if they are stored / encrypted / decrypted securely, with some patience he would sniff them all.
When the application is first run, it will generate a random key. This key will be used to encrypt and decrypt sensitive data. Store the key in a local file, and set the file permissions so that nobody else can read it. Ensure that the user running the web server has no login access (this is a good idea anyway).
Possible ways to break this system:
Get root access.
Get sudo access.
Deploy a malicious application on the web server - this application will then have access to the key, and may be able to send it elsewhere.
As long as you take reasonable precautions against all of these, you should be OK.
EDIT: Come to think of it, you could just store the sensitive data right in the key file. Encryption would provide an extra layer of security, but it wouldn't be a very strong layer; if an attacker gets access to the file, chances are good that he also has access to the DB.

What is the best way to keep passwords configurable, without having them too easily available to the casual human reader?

I have a database that many different client applications (a smattering of web services, some java apps and a few dot net applications) connect to. Not all of these are running on windows (Sadly, otherwise it would make this an easy answer question with just enabling windows authentication for database connections). At the moment, the passwords are stored in various configuration / properties files lying around the systems. Ideally, only the support staff have access to the servers where the files are running, but if someone else gains access to one of the servers, they would have enough database permissions to get a fair whack of data as it stands now.
My question then, What is the best way to keep the passwords configurable, without having it too easily available to the casual human reader?
Edit Just to clarify, DB server is Windows Server 2003, running MSSQL 2005.
PS: I don't see any questions that this duplicates, but if there are, please feel free to close this one.
I'm assuming you want to hide the passwords from casual observers. If they were evil, steely eyed observers with access to all the source code on one of the machines that connects, then they can get the password with a bit of reverse engineering.
Remember that you do not need to use the same protection for each different client. A few steps:-
Create different database accounts for different systems that access your database
Limit access on the database to only what they need using your inbuilt database GRANTs
Store a triple DES (or whatever) key inside a password manager class on your database. Use this to decrypt an encrypted value in your properties file.
We have also considered having the application prompt for a pass-phrase on startup but have not implemented this as it seems like a pain and your operations staff then need to know the password. It's probably less secure.
Let's assume the following common scenario:
You use the same code base for all environments and your code base has the database passwords for each environment.
The personnel (sysadmins, configuration managers) that have access to your production application server are allowed to know the production database passwords and no one else.
You don't want anyone with access to the source code to know what the production passwords are.
In a scenario like this, you can encrypt and store the production passwords in property files that your application. Within the application you can include a class that reads the passwords from the property file and decrypts it before passing it to the database driver. However, the key and the algorithm used to decrypt the password are not part of the source code but rather passed to the application as a system property at runtime. This decouples the knowledge of the key from the application source code and anyone with access to just the application source code will no longer be able to decrypt the password because they do not have access to the application's runtime environment (app server).
If you are using Java take a look at this for a more concrete example. The example uses Spring and Jasypt. I am confident that some thing like this can be extrapolated to other environments like .Net
At my old workplace we used to have a system whereby all passwords were encrypted (using Triple DES or whatever we were using at the time). The passwords were often stored in properties files (this was in a Java system).
When the password needed to be changed, we could simply use "!plaintext" as the value, and then our code would load it up, encrypt it, and store the encrypted value back in the properties file.
This meant that it was possible to change the password without knowing what the original value was - not sure if that's the kind of thing you were asking for!
It sounds like there is no easy answer (because of the different types of applications that connect)... really, the only issue I see is the Java Apps which seem to connect directly to your database. Is that correct?
If so, here's what you can do:
1) Change any client-side applications that connect directly to the DB to go through a service. (If they have to connect directly, then at least give them a first step to "get password" from a service, then they can connect directly).
2) Store the passwords in the web.config file (if you chose to do .Net web services), and then encrypt the "connection strings" section of the file.
Don't use passwords, server to server authentication can usually be performed by using a key file or a client cert or some other way other than a password.
You could use a reversible encryption algorithm e.g. Blowfish to store the passwords as a stopgap measure. There should be a number of free libraries you can use to build this into all your programs that need this access.
Bruce Schneier's page on Blowfish
Wikipedia article on Blowfish
For the java stuff, if you're using an app server see if you can define a data source, and your apps can get at the data source using JNDI. That way, managing the datasource (including connection details) is handled by the app server, and your application code has to do is ask for a datasource.
NTLM Authentication or LDAP-based (Active Directory) authentication should be available to you with a bit of effort. This would allow you to use your "windows authentication" across applications.
It may mean a bit of a migration for your operations staff, but SSO for a set of applications is nice.
Yes I have to agree with the option of storing the (salted) hashes. I would recommend a (salted) SHA256 hash of the password stored in the database. Also don't forget to enforce secure password rules.
My interpretation of your question is that you are asking specifically how to store configuration passwords that your code will use to connect to services it depends on such as a database or third party API. In that case, you may want to consider using a service which provides a secrets container such as Hashicorp's Vault.
You can think of vault as a web service your application can connect to in order to lookup the secrets your application needs at application runtime.
As an example, lets assume your application needs to connect to a database but you don't want to store your database credentials with your application source code in your version control system. Furthermore, lets assume that you want the database credentials used by your application to be different each time your application starts. In this case, you could enable and configure the database secret back end in vault. This means that vault will dynamically create your database credentials as a service, and then provide your application with a revocable leased token for some duration of time. Vault, of course, will allow you to store any secret in it.
Vault provides secure ways for your application to connect to it. One such authentication method uses what is known in vault as the Cubbyhole Secrets Engine.
Using encryption is not a good idea. If someone compromize the key he can decrypt it. Use a hash algorith with salt to store paswords. Hash algorithms are one way so its not reversible. But they are vulnerable to dictionary attacks so use salt (concatane plain text with something long and verbose than hash it). It also protect database from internal attacks.

Resources