I am currently working on an application which allows users to save sensitive date. Since it's a web application we are using NodeJS
and MongoDB
for persistence. (BTW I am completely new to Node and NoSQL)
We do have users who can store kind of a medical history. Name and email are stored within a user document while the other stuff is stored within the profile.
To improve security I would like to encrypt
the references from a user to his profile and vice versa.
At the moment I am using the Crypto
library of NodeJS
to encrypt (AES256) the user_id
reference within the users profile. As a consequence the reference is not a type of ObjectID anymore but a string
So by viewing the database directly it is not possible to check which profile belongs to which user. The secret key to encrypt
and decrypt
the users id is stored somewhere in a js file of the NodeJS
server.
Is this a common/good way or am I doing something completely wrong? Are there any better ways – I read that mongoDB is not supporting any "built in encryption"
At least, here is the code for the en/decryption
module.exports = function() {
this.encryptionSecret = "ANYSECRET";
this.crypto = require('crypto');
this.algorithm = 'aes256';
this.encrypt = function (key) {
var cipher = this.crypto.createCipher(this.algorithm, this.encryptionSecret);
var encrypted = cipher.update(""+key, 'utf8', 'hex') + cipher.final('hex');
return encrypted;
};
this.decrypt = function (encryptedKey) {
var decipher = this.crypto.createDecipher(this.algorithm, this.encryptionSecret);
var decrypted = decipher.update(encryptedKey, 'hex', 'utf8') + decipher.final('utf8');
return decrypted;
};
};
Let's take a look at the risks you're facing:
A hacker breaks into your server and steals the entire DB. Bad luck, in this case, encrypted references won't help much since the hacker likely got access to the key, too. Even if you completely federate the data, e.g. to different data centers, and the hacker only gets the 'anonymous' part of the data, those medical records will probably contain name, insurance and/or other identifying data. Even if not, there's research that shows that it's almost impossible to anonymize data (examples: anonymized friend graphs, device profiles)
A hacker hacks your site and gets access to data outside his account Since your server must be able to handle the de-referencing logic and must have access to both data stores to perform its duty, this method won't add security at all. However, since you're using a server technology that is completely new to you, the chances of having security holes in your software are high...
The disk crashes and you lose part of the data or the key In that case, you'll have more work to do than recovering from a similar scenario without encrypted references.
Making web applications safe boils down to one-and-a-half possibilities: Either make the system itself as robust as possible by using secure coding standards, penetration tests, intrusion prevention, two-factor authentication, etc., etc. and/or use client-side encryption. The latter looks like the ultimate weapon, but is fraught with its own perils. I'm afraid there's no silver bullet [that I can think of].