Credentials security vulnerability

Node red can encrypt some values to flows_cred.json. Can set password in settings.js to have this encrypted, basically having its own key vault. However, I find some vulnerabilities with this approach.

Main issue is secrets and encryption only applies for obscured text boxes. This means a limited amount of nodes and a limited set of values within each node. All other values are written in clear text in flows.json. For example when I connect to login to remote API, I write username and password in function node, to add them to payload.

A minor issue is, if encryption password is later leaked. Having access to source files fine, because passwords are encrypted. An attacker could get hold of flows_cred.json but still not see contents. Until getting the password.

My approach was to use a separate .env file. This is loaded when node red starts and available in-memory in all flows. The secrets are never stored in any node-red code or in git repo. This of course requires a separate key vault, which you must have anyway since you need somewhere to store/share the password when using node-red's built-in alternative.

How good is node-red's approach with built-in secret encryption when it doesn't cover everything?

Environment variables seem to be a good work-around for things like secret API keys.
Is your .env file encrypted?
If so can you explain how you achieve it please?

1 Like

No the .env file is unencrypted. But it's added to gitignore and must be copied to the project folder manually. Should probably look into encrypting it too, however that still leaves the encryption password to be handled some way in the project and node-red program? Maybe as command-line arg.

Not if you set the env var to credential type input, it is then stored in the flows_cred.json
[edit] for clarification we are communicating past each other. I am saying to use flow group or global env vars, not a env file.

Do you mean you read the file into the flows at run time, or do you mean that it is a true environment file which sets environment variables that are not stored in the node red runtime at all?

I don't think the contents of an environment variable are stored anywhere in the node red files are they? They can vary from run to run so can't be.

As far as i understand and flow, group or global env var that is of type credential is stored encrypted, I may be wrong i wait to be corrected.

It can't store the env var contents because they are not known to the editor. It could store the env var name, but not the contents.

Try adding a flow environment var credential and see if you can see it after you enter it and deploy. Then try exporting the flow and see if the credential is exported.

As soon as the flow is deployed the credential is encrypted by the server.

[edit] I think we are communicating past each other , i am referring to flow, group and global env vars, not an enviroment file.

Couple of things here.

Firstly, environment variables are not "Secure" (capital S) - in the sense that they exist in a server memory space that is actually quite easy to access (which is why Node.js has a library that lets to access them very easily). So while many people and websites that should know better present them as a security feature, they really aren't.

However, they can be better than storing them in an unencrypted file in the sense that it can be marginally harder for an attacker to discover them.

Secondly, when using a .env file, you need to make absolutely certain that the user id running node-red (or any other daemon code other than systemd) cannot access the file. For example, if you make the file owned by root, systemd will be able to access it at boot time but your nodered user will not - AS LONG AS, you aren't foolish enough to run Node-RED as root (which I know, no matter how often we tell people not to, some still do) or to put the nodered user into the admin or other privalaged group.

Lastly, the best way to secure sensitive access keys is in an HSM (Hardware Security Module). 2nd best is to use the software-equivalent, a keystore. You will need a mechanism to retrieve the appropriate key value at node-red startup time of course and then you are back to the original issue - assuming that Node-RED runs all the time, the key will be in an in-memory environment variable. A better solution would be a custom node that reads the key value from the keystore only when it is needed and deliberately removes it from memory straight afterwards.

Having said all that, much of this is severe overkill for many of the applications discussed in this forum and probably only worth it if you have paying customers with valuable data.

For everyone else, the secured .env file, accessed by the systemd startup script is going to be good enough. Just make that file only root accessible and that Node-RED does not have elevated privileges.

1 Like

Those are not system level environment variables, they are ones created within node-red itself, and values defined in the node red editor. Here we are talking about environment variables set at system level which node red picks up at run time from the OS. So, for example, an environment file may be read in by the systemd startup script which makes the variables accessible to the node red runtime as env vars.

Indeed so, those are what @jbudd and I are suggesting to use, not an environment file. I have clarified this in above posts. I also linked to a post that mentioned the flow, group and global env vars, you must of missed that.

Understood, eventually :slight_smile:

Well actually I was referring to an environment file loaded by systemd at startup, since that is [similar to] what the OP says he uses.

But after running this little flow I think I'd have to reconsider my statement that environment variables are a good solution:

Oh, I assumed (maybe misread) that's is what you were suggesting, as an env file would not encrypt the secret.

I still suggest using flow, global or group env var credentials, as they are encrypted.

Unfortunately I can (as long as I know it's name):

If an intruder is able to edit and run the flows then I think all bets are off. Even an encrypted group variable, for example, can be picked up by a Function node, at which point it is decrypted.

@jbudd
You can access it, yes, it would be useless if you could not
You can not export it in a flow
It can not be seen in the env config.

Of course. Node-RED is a general purpose development environment that is MASSIVELY powerful.

If you give the Node-RED Editor access to people, it is possible for it to be abused if you aren't very careful.

HINT: That code returns ALL of the current system environment variables.

Actually it does not seem to reveal my $BankAccount credential flow variable.