Skip to content

Commit

Permalink
Save bcrypt password checks s in local memory (#6)
Browse files Browse the repository at this point in the history
  • Loading branch information
Alkarex authored Oct 17, 2023
1 parent 42018e1 commit f621c92
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 9 deletions.
10 changes: 8 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,14 @@
This Node-RED module performs [HTTP Basic authentication](https://developer.mozilla.org/docs/Web/HTTP/Authentication).
It is to be used in conjunction with an [HTTP Input node](https://cookbook.nodered.org/http/create-an-http-endpoint).

Supports [bcrypt](https://en.wikipedia.org/wiki/Bcrypt) to store passwords
(such as in the [Apache password format](https://httpd.apache.org/docs/current/misc/password_encryptions.html)).
In other words, it allows putting a password on a Node-RED HTTP listener node.

Note that this standard protocol sends passwords in plain-text by design, so HTTPS is required to ensure the security of the transmission.

Supports [bcrypt](https://en.wikipedia.org/wiki/Bcrypt) to store passwords on disc
(such as in the [Apache htpasswd format](https://httpd.apache.org/docs/current/misc/password_encryptions.html)).
Note that this node will cache the bcrypt checks in memory (until the flow is redeployed / restarted)
to improve performance (bcrypt is slow by design, to protect passwords on disc).

## Example

Expand Down
18 changes: 17 additions & 1 deletion nodes/http-auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ try {
bcrypt = require('bcryptjs');
}

/**
* Cache in local memory the bcrypt decryption (which is very slow by design).
* Reset when the flow is redeployed or restarted.
*/
const bcryptCache = {};

function passwordCompare(plain, hash) {
if (plain == '' || hash == '') {
return false;
Expand All @@ -18,7 +24,17 @@ function passwordCompare(plain, hash) {
// Compatibility work-around for 'bcrypt' library
hash = hash.replace(/^\$2[x|y]\$/, '$2b$');

return bcrypt.compareSync(plain, hash);
if (plain === bcryptCache[hash]) {
return true;
}

const success = bcrypt.compareSync(plain, hash);

if (success) {
bcryptCache[hash] = plain;
}

return success;
}

function basicAuth(authStr, node, msg) {
Expand Down
10 changes: 5 additions & 5 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@alexandrainst/node-red-http-basic-auth",
"version": "3.0.0",
"version": "3.1.0",
"description": "Node-RED node for HTTP Basic Authorization",
"keywords": [
"node-red",
Expand All @@ -9,6 +9,9 @@
"basic",
"auth",
"authorization",
"access",
"htpasswd",
"password",
"rfc2617",
"rfc7617"
],
Expand Down
1 change: 1 addition & 0 deletions test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
test=$(
cat <<'EOF' | node ./index.js http-basic-auth --realm='"node-red"' --username='"test"' --password='"$2y$10$5TSZDldoJ7MxDZdtK/SG2O3cwORqLDhHabYlKX9OsM.W/Z/oLwKW6"'
{"req":{"headers":{"authorization":"Basic dGVzdDp0ZXN0"}}}
{"req":{"headers":{"authorization":"Basic dGVzdDp0ZXN0"}}}
EOF
)

Expand Down

0 comments on commit f621c92

Please sign in to comment.