4

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;
    }; 

};

Alexander
  • 7,178
  • 8
  • 45
  • 75
  • 2
    Is "what" a common way? Storing a key in your source code? It's certainly not ideal, but you'll find that key management is difficult and it will need to be stored somewhere, in a config file, encrypted by an account, etc. Your technique of "protecting" the data seems very weak (as studies have shown that it's relatively straightforward to identify patients from even semi-anonymized data, and in this case, all you're doing is encrypting the reference, but not the data). – WiredPrairie Aug 06 '13 at 15:29
  • First of all, great thanks for your answer @WiredPrairie ! Do you have any suggestions on what to do either to improve safety / the anonymization of the data? If keeping the data itself encrypted is not the best way, what would be the alternative? – Alexander Aug 07 '13 at 06:13
  • Thanks for the module. Works very well. One could pass in the secret via the constructor to make it more flexible. – Henry Sep 04 '14 at 06:29

2 Answers2

4

Let's take a look at the risks you're facing:

  1. 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)

  2. 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...

  3. 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].

mnemosyn
  • 45,391
  • 6
  • 76
  • 82
0

I would recommend putting your encryptionSecret in an environment variable.

Eric
  • 586
  • 1
  • 5
  • 19
  • and then what about the scenario (mentioned in answer) that the server is hacked? environment variables are easily accessed (with for instance `printenv`). The key is not then safe. – amlwwalker Jul 06 '16 at 22:48
  • I suppose if your server is hacked then you're out of luck. Not only are your environment variables easily accessed, but literally everything your app has access to will be available to the hacker. --- I don't think having your server hacked is a common scenario that people defend against. They usually just defend themselves against being hacked in the first place, but not once a hacker is already in. – Eric Jul 07 '16 at 00:34