Allow the user to change his/her password for dashboard UI

Hi, I'm thinking about giving the user a way to change - from the dashboard - autonomously his/her own HttpNodeAuth user password. Each and every F/E allow the user to do that why not Node-Red too?!??

What about using for instance a NR flows consisting of:
A. a Bycrypt node in order to compute the bycrypt has of the new password
B. a simple find/replace sed command inside an "exec" node in order to replace the old bycrypt hash with the new one
C. a NodeRed restart driven by another "exec" node in order to get the new settings.js reloaded

What are the risk conected with this option?

Is it possible to edit the settings.js file while NR is running?

Thanks in advanced

Hi Lenny.

I think that idea goes against the idea of having security log ins.

I am (probably and usually) wrong.

But think about it.

Yes, the way you are describing could work.
It would require external programs to run.

But the password needs to be encoded as well. So that is more steps.

Is it really worth that effort for the gain?

In reply to the last part:

From my knowledge:
Yes - kind of.
You edit it and then restart node-red.

Again: Is the gain worth the effort?

Hi Andrew,
the fact is that each and every front-end you provide to the end-user - and that is user/passwrod protected - allow the user to change the password by himself for security reasons - most important - and for mnemonic reasons too.

I don't understand why you say that it would require "external program to run" (the password change flow will be managed entirely within the NR flow and will use already available node-red palettes). Consider then that with about 15 or 20 total nodes it's possibile to define all the logic/check required during a standard password change procedure (i.e. asking the user to input the password twice and check for specific password syntax for the new password definition).

It's not so clear to my - probably for my bad english - the following sentence

What do you exactly mean?

The first part: I didn't know nodes exist to allow users to change their passwords.

(Not your fault. I failed English at school.)
Second: I someone gets your password, they can log in change the password and then you are totally locked out.

I'm going to creare a flow that allow the user to chenage his/her password. Not any "ready-to-use" node/palette is available afaik.

The dashboard will be used by my "customer" so it will be his/her dashboard. Additionally I'm implementing also a way to change remotely the user password by sending configuration messages via MQTT. So, for any reasons, I can reset/change his/her password from remote at any time.

On the base topic, it’s generally discouraged to have nodes edit settings.js files. Editing it from your flow, followed by a restart brings in risks too. You have to ensure the exact right part is edited, and that the file stays a valid JavaScript file. After edits to the settings file, node-red has to be restarted to read in the changes. If there are errors in the file, node-red will fail to start, and you break your running system until you fix it by hand.

The following is a quote from Nick on a less visible part of the forums, in a topic about editing the settings file from a node.

1 Like

I agree with what was just said.

Also, I am missing a bit about why your customers need to edit their flows.

It is a real can of worms you are opening allowing passwords to be changed ad hock.

I don't believe this is about editing flows. This is about securing a Node-RED Dashboard UI - and allowing the end user to change their password to access the Dashboard (not the editor).

As has been said, editing the settings file is not recommended. You could change the settings file to load the httpNodeAuth value from another file - and then create a flow that edits that file safely. But you cannot avoid the need to reload Node-RED to pickup any changes.

We know the auth options for Node-RED Dashboard are pretty limited. Ideally it would have a more fit for purpose auth scheme rather than limited to a single, hardcoded username/password from the settings file. However that's all we have today.

1 Like

Oops.

Sorry. I don't even know what that means.
I know a bit about getting HTTPS working, but that is beyond my needs and I have left it alone.

You're right Nick.

I'm aware of the risk incurring having a malformed settings.js file but using sed functionalities (by searching the line for httpNodeAuth string and then entirely replacing the whole line found with a new one - always using sed commands) will be quite safe for me. Even modifying the settings.js file with nano from the host (by SSH to the RPI hosting NodeRed) should bring to error and typos and make NodeRed unable to start again.

Anyway I really appreciate your suggestion about loading httpNodeAuthcredentials externally . Can me point to the way to load the httpNodeAuth from an external file? Are there some example to follow?

I would store that data in a JSON file alongside your settings.js and include it with require. You can easily generate valid JSON strings using the json node or JSON.stringify() from within a function node.

In your settings.js file, using a try/catch around it would be wise, so you can handle errors like invalid format or missing file. Use default values in that case, so Node-RED can start properly.

You'd have to restart your Node-RED process, of course.

Oh, and don't forget to create the proper password hash like the node-red-admin hash-pw command line tool does.
Here's a pointer: https://github.com/node-red/node-red-admin/blob/master/lib/commands/hash.js

1 Like

Thanks Matthias for your suggestion. I'll going to explore this option too.

I belive that the correct way to do this is to use an external module require'd into settings.js that gets its user id/password hash data from another source.

You should then provide a REST API that a user-facing page interacts with in order to allow users to change their passwords.

The REST API could be provided by a node-red flow but it would be more robust and very likely more secure to do it in a custom node.

The reason for using an external require'd module is to allow for better coding practices and support multiple customer configurations should you need to. It also will be easier to code and test.

Using a REST API will let you draw on standard code from other sources to help you with your UI. Please remember that getting a secure login is not straight-forward and ALWAYS get the resulting system penetration tested if using in a production environment with customers.

It shouldn't need to be said that none of this makes any sense at all unless you have secured access to your UI and Node-RED using TLS encryption (https). It also shouldn't need to be said that you should never store use passwords, you store the hash of the password.

Where the user data is actually stored doesn't matter especially unless you are looking to support hundred's or more users. A JSON file as Matthias says is fine for smaller numbers. SQLite for middling numbers but a proper database engine should be used for larger numbers and resilience/load-balancing.

2 Likes

I was just picking up on the initial idea of editing the settings.js.
I wouldn't do that myself in practice either, but developing a more maintainable and portable approach like the one you described. :slightly_smiling_face:

I do not recommend the approach of permitting users to change their passwords (or anything in the settings.js file) for the simple reason that deploying these changes requires a restart.

This violates the basic "availability" concept in IT security because if two users are on the system at the same time, if one user restarts the system, the other user can lose data. Imagine if you have many users on the system and have many users working and one person restarts on Node-RED.

You need to maintain control over the start/stop/restart Node-RED process and writing code to hand this over to "users" so they can change their password is not a good idea, in my view.

As others have mentioned, it is also a basic IT security tenant to insure integrity of a file; and settings.js needs to have high integrity. If two users attempt to update their passwords (or anything in settings.js) at the same time, this could cause serious conflicts and potential corruption of settings. js.

If I had many Node-RED users, this is best done by sending a request to the "Node-RED Admin" so they can schedule changes and restarts to Node-RED at the appropriate time.

You might consider creating a node which permits a user to generate their own password hash, so they can send the "Node-RED Admin" person the hash of their password versus the actually password, but other than that; as other have advised, it is better not to create a user process to "mess with" settings. js and restarts. However, be careful in this approach because sending hashes also has security concerns.

1 Like

Unixneo, Node-Red dashboard is single user so the problem that you describe it's already "a problem". In my scenario, the UI Dashboard will be always used by one and only one user. The user - for different reasons - need to have a way to change his/her password "autonomously" (the reasons should be different : i.e. password compromission, use a mnemonic password and so on) . And this activity has to be made without others intervention (I avoid to explain you why...).
In this scenario a self-change password procedure it's - in my opinion - a "need-to-have".
Having this requirement there are different way to accomplish that (using an external "resource" to manage the secrets in a JSON file or in an external DB, having a procedure to modify directly the settings.js file and so on).

I don't think that self-service password reset is an issue. This is a common and modern practice and done properly is secure. Certainly it reduces admin costs and improves customer service.

The main thing here is avoiding changes to settings.js and avoiding having to restart Node-RED. This isn't that hard to do but does take some initial setup.

By the way, if you are looking for a more flexible, securable multi-user front-end capability, you might want to track the security branch of uibuilder as that is where I'm working on just that issue. In addition to enabling you to simply add user id/authorisation processing, it should also allow you to correctly secure the websocket channel.

Then, if you are in a "single user" situation (and like you say, as I understand it the Dashboard UI is still, unfortunately, "single user" anyway)...

The one method is to have your node call an API where the new password is sent via the API (I assume you are using HTTPS).

  • Move or save the exiting settings.js file to something like settings.js.timestamp.back
  • Create a new settings.js file with the new user password (no need to edit the existing one) hashed in the API;
  • With the original settings.js file saved, write the new settings.js file your API just created
  • Restart Node-RED

You could also do it like this:

  • Create a new settings_timestamp.js file with the new user password hashed in the API;
  • Restart Node-RED with the switch to restart Node-RED with the settings_timestamp.js file using:

node-red --settings settings_timestamp.js

something like that....

This is an easy API to write.

There really isn't a need to do this. Node-RED already provides methods to let you offload authentication to an external function. You don't need to mess with settings.js other than to make a single change to use a function instead of a fixed list.

@TotallyInformation httpNodeAuth cannot be a function - it must be a hardcoded username/password pair - https://nodered.org/docs/user-guide/runtime/securing-node-red#http-node-security

So yes, you do need to rewrite something that gets loaded into settings.js and restart Node-RED.