3

I'm pretty new to node.js and have been asked to create an application (website) where users can login with their AD account that has elevated privileges. The goal of the application would then be to launch different PowerShell scripts and other tools with these elevated credentials.

After searching the web it seems we need the following packages:

It seems that it's not a good idea to store the username and password in the payload of the jsonwebtoken. The token is supposed to stay lightweight and only hold a unique identifier for the AD user (this could be his DistinguishedName I guess).

My questions: Where is the AD password stored for the user? If it can't be in the jsonwebtoken, the only place left is probably a database? Is this the secure way of doing it? If the database is compromised it seems unsafe too.

And if the database stores the AD password, we will need to request an AD credential object each time the user fires a PowerShell script. Would it be better to store the complete AD credential object in the database and not only the AD password?

I might be over-complicating things, but thank you for clarifying this for me.

DarkLite1
  • 13,637
  • 40
  • 117
  • 214
  • You can store passwords in the database using [bcrypt](https://www.npmjs.com/package/bcrypt) which is in the end also supported by passport. – Jankapunkt Feb 05 '20 at 21:35
  • When the DB is compromised can the passwords be decrypted? Can the app decrypt the password when it is required? – DarkLite1 Feb 06 '20 at 07:50

2 Answers2

3

Solution by using NodeJs internal Crypto Library

  1. Generate a public and private key files using crypto.generateKeyPairSync(), by choosing choice of encryption. Example code from same page:
const { generateKeyPairSync } = require('crypto');
const { publicKey, privateKey } = generateKeyPairSync('rsa', {
  modulusLength: 4096,
  publicKeyEncoding: {
    type: 'spki',
    format: 'pem'
  },
  privateKeyEncoding: {
    type: 'pkcs8',
    format: 'pem',
    cipher: 'aes-256-cbc',
    passphrase: 'top secret'
  }
});
  1. Use the crypto.publicEncrypt(key, buffer) in your code to encrypt the passwords and store them in Database. While reading back the value use crypto.publicDecrypt(key, buffer) to get the original value.
  2. If you want to read the values outside your code, use privateDecrypt() and privateEncrypt() values along with Passphrase.

This will ensure security concern while in database or over transit/wire.

kn_pavan
  • 1,510
  • 3
  • 21
  • 42
  • Perfect, thank you very much. Is there also a need to `salt` a password when it's stored as an encrypted string in the database? I might also consider using `bcrypt` as that is widely known and used I think. – DarkLite1 Feb 06 '20 at 11:54
  • If you are using `crypto` additional `salt` may not be needed, but depends on your security preference. – kn_pavan Feb 06 '20 at 12:05
-1

You no need to deal with AD passwords at all, just put your node app behind IIS, disable anonymous authentication and enable Windows authentication, it will do the job right and you will be able to run scripts with authenticated user identity. You can take a look at https://github.com/auth0/passport-windowsauth on first example, you may no need to have more advanced setup for your simple use case.

vitalyster
  • 4,980
  • 3
  • 19
  • 27