how to fix tsr-detect-possible-timing-attacks potential timing attacks - javascript

I have code like this:
if (!confirmPassword) {
errors.confirmPassword = DefaultValidateErrors.confirmPassword;
} else if (password && password !== confirmPassword) {
errors.confirmPassword = DefaultValidateErrors.confirmPasswordMatch;
}
tslint has flagged this as tsr-detect-possible-timing-attacks which sounds correct but how do I fix it.

If you are in node and version v6.6.0+, then you can use the crypto module's timingSafeEqual.
const crypto = require('crypto');
const isValid = crypto.timingSafeEqual(Buffer.from(password), Buffer.from(confirmPassword));
Node crypto docs

I think this is a false positive and you can just suppress the lint warning. The lint rule looks for any variable named password, but a timing attack is only relevant when data unknown to the client is involved, e.g., when checking a password specified by a client trying to log in against the saved correct password. It looks like this code is just validating a new password being set by an authenticated user.
That said, for avoiding timing attacks when they are relevant, a web search found me the rule documentation, which links to a post with a suggested solution to compare two passwords in constant time using bitwise operations. (You would think that functionality would be in a library somewhere. Maybe it is.)

Related

password authentication token / Nodejs - Express JWT

I'm having trouble logging into the server to do the authentication tests for my JWT password token, it claims problem
no " required:jwt({"
grateful to whoever helps me
user side of authentication
I tried changing the commas but the problem persisted I believe it is something deeper
You should require the library with a different syntax, reading documentation:
const { expressjwt: jwt } = require("express-jwt")
Also, it looks that the algorithms property is a required option. Therefore, on line 20 and 25 of your code, you want to write something like:
jwt({secret:'secret', algorithms: ["HS256"], userProperty: 'payload', getToken: getTokenFromHeader)
The above example just works. Of course you should choose the right strategy and the right algorithm for a strong authentication.
const { expressjwt: jwt } = require("express-jwt");

How to verify that a a user string input doesn't contain sql injection? in Javascript

I tried to dig in the sanitize function but i didn't find the answer that I wanted, the question is how to check if a user input doesn't contain any sql injection? i'm using Nest JS (similar to node) if you have any idea of how I can do that it would help me a lot!
Generally speaking: You can't. Any input which might be SQL injection could, conceivably, also be genuine input (at least in certain narrow circumstances).
Don't try to detect SQL injection. Instead, use placeholders where possible and proper escaping where not.
The issue is not on the NestJS side, it is on how you build the SQL query to execute.
You may use #nearform/sql that:
A simple SQL injection protection module that allows you to use ES6 template strings for escaped statements. Works with pg, mysql and mysql2 library.
It will protect you against malicious users input.
This module is battle-tested and already in production for Covid Government Tracker.
You can use prepared statements to avoid sql injection attacks
This blog post explains it quite well. for reference a snippet from the post.
function authenticate(req, res, next){
const username = req.query.username,
password = req.query.password
let preparedStatement = new sql.PreparedStatment(),
sqlQuery = "select * from users where (username = #username and password = #password)"
preparedStatement.input('username', sqlVarChar(50))
preparedStatement.input('password', sqlVarChar(50))
preparedStatement.prepare(sqlQuery)
.then(function(){
return preparedStatement.execute({username: username, password: password})
.then(function(recordset){
if(recordset.length == 1){
loggedIn = true
//successful log in
} else {
//authentication failed
}
})
})
.catch(next)
}

nodejs - how to compare two hashes password of bcrypt

Hello I need some help with this issue after I search the solution and I have not found yet,
I want to compare 2 hash password with bcrypt of the same password,
how do I do it?
for example:
I have these 2 hash password that came from the same password in bcrypt:
var password = E#Js#07Do=U$
var hash1 = $2a$10$fKAyjaG0pCkisZfRpKsBxursD6QigXQpm1TaPBDZ4KhIZRguYPKHe
var hash2 = $2a$10$mgApOcRIp7RSK3lRIIlQ5e/GjVFbxAFytGAEc0Bo17..r8v2pPR22
// that's not working for me
bcrypt.compare(passwordHash, userPasswordLoginHash, function(err, isMatch) {
if (err) throw err;
if(isMatch){
console.log('correct password!')
}
callback(null, isMatch);
});
how can i compare them, to determine that they came from the same password, by using bcryptjs npm package?
This is impossible by design - as a core security property of true password hashing.
If you could compare two password hashes without knowing the original password, then if an attacker cracked one password on the system, they would instantly know the passwords of all users who are using that password, without any additional work. It should be immediately obvious why this would be a bad thing.
For example, if passwords were stored using a hash inappropriate for password storage (such as MD5), then if 50 users had a password of 'password', then all of their hashed passwords would have the identical MD5 hash ('5f4dcc3b5aa765d61d8327deb882cf99'), and cracking one of them would reveal the password of all 50 users.
You can't do that with a modern password hash like bcrypt. The only way to "compare" two modern password hashes is to know the plaintext in advance, and then apply the algorithm using the salt in each hash. And even if two users have the same password, the attacker has to perform the same expensive computation to crack each of them independently, because the unique salts make each hash unique.
More generally - and this may sound a bit bold - but there is no legitimate use case for any system or administrator to ever compare two different users' passwords. User passwords should be 100% independent and 100% opaque to the system once stored. If a system or business case requires this kind of comparison, it should be redesigned to eliminate that requirement.
"With bcrypt lib you compare plain text password to the one hashed using the same lib."
The problem is with a micro services architecture, that is very insecure. If I have a front end passing an unhashed password to the backend, the unhashed password is getting logged (possibly in multiple places) before it gets compared against the hash in the DB on the system backend.
With bcrypt lib you compare plain text password to the one hashed using the same lib.
Say you hashed a password
const myPlaintextPassword = 'E#Js#07Do=U$'
bcrypt.hash(myPlaintextPassword, saltRounds, function(err, hash) {
// Store hash in your password DB.
// example output, taking your hash
// hash = $2a$10$fKAyjaG0pCkisZfRpKsBxursD6QigXQpm1TaPBDZ4KhIZRguYPKHe
});
You compare like:
// db query, get hashed password, found hash
// hash = $2a$10$fKAyjaG0pCkisZfRpKsBxursD6QigXQpm1TaPBDZ4KhIZRguYPKHe
// User input again:
const myPlaintextPassword = 'E#Js#07Do=U$'
bcrypt.compare(myPlaintextPassword, hash, function(err, res) {
// res is true as the original password is the same
// res == true
});
For a bit extra security you can encrypt the password in the front-end and decrypt and compare in the back-end

How to properly configure MAIL_URL?

The follwoing smtp url giving me an error
process.env.MAIL_URL="smtp://mail_name#outlook.com:Password#smtp.outlook.com:457";
What am I doing wrong?
For starters, your issue is that your user name (and perhaps your password) contain a character that cannot be placed in a URL as-is, and therefore needs to be encoded.
I want to take this opportunity to provide a little more in-depth answer to the issue of configuring the MAIL_URL environment variable.
If you simply need a quick string that will work, do:
process.env.MAIL_URL="smtp://"+encodeURIComponent("mail_name#outlook.com")+":"+encodeURIComponent("Password")+"#smtp.outlook.com:457";
Also take into account that you may need to use smtps for secure connection, and if it uses TLS, your connection may fail.
I recommend to read the rest if you need anything more robust.
URL
A URL has the following structure:
scheme:[//[user[:password]#]host[:port]][/path][?query][#fragment]
The scheme would be either smtp or smtps (for secure connection), and in this scenario you will also set the user, password, host and (most likely) port.
Each of the parts needs to be encoded in a way that is suitable for use in a URL, but since hosts (domains) are normally already appropriate, you only need to make sure that your user name/password are encoded.
In EcmaScript, encodeURIComponent can be used for this.
MAIL_URL and node environment variables
Meteor checks the value of process.env.MAIL_URL when sending an email.
process.env is populated by node.js with the environment variables available to it on startup.
It is possible to add properties to it on runtime, so setting process.env.MAIL_URL before sending an email will work. However, you should do so wisely to prevent your secrets from leaking.
I would suggest 2 methods for setting it up, either using settings.json or using the environment variable itself.
using settings.json
Create a json file in your project. It is highly recommended not to commit it into source control with the rest of your code.
for example: config/development/settings.json
{
"smtp": {
"isSecure": true,
"userName": "your_username",
"password": "your_password",
"host": "smtp.gmail.com",
"port": 465
}
}
And somewhere in your server code:
Meteor.startup(function() {
if (Meteor.settings && Meteor.settings.smtp) {
const { userName, password, host, port, isSecure } = Meteor.settings.smtp;
const scheme = isSecure ? 'smtps' : 'smtp';
process.env.MAIL_URL = `${scheme}://${encodeURIComponent(userName)}:${encodeURIComponent(password)}#${host}:${port}`;
}
});
Then you can run Meteor with the --settings switch.
meteor run --settings config/development/settings.json
using an environment variable
You can set the environment variable to the encoded string. If you want a utility script (for zsh on *nix) that will convert it (depends on node):
mail_url.sh
#!/bin/zsh
alias urlencode='node -e "console.log(encodeURIComponent(process.argv[1]))"'
ENC_USER=`urlencode $2`
ENC_PASS=`urlencode $3`
MAIL_URL="$1://$ENC_USER:$ENC_PASS#$4"
echo $MAIL_URL
which can be used as follows:
$ chmod +x mail_url.sh
$ MAIL_SCHEME=smtps
$ MAIL_USER=foo#bar.baz
$ MAIL_PASSWORD=p#$$w0rd
$ MAIL_HOST=smtp.gmail.com:465
$ export MAIL_URL=$(./mail_url.sh $MAIL_SCHEME $MAIL_USER $MAIL_PASSWORD $MAIL_HOST)
$ echo $MAIL_URL
smtps://foo%40bar.baz:p%4015766w0rd#smtp.gmail.com:465

Nodejs bcrypt library

I use the nodejs bcrypt library for better password protection.
I am not sure i understand exactly how to use it, but i got this so far:
//A module containing this login function:
login: function(credentials,req,res) {
//"credentials" is containing email and password from login form
var query = 'SELECT password, email FROM users WHERE email = ? LIMIT 1';
client.query(query,[credentials.email], function(err, results) {
if (results[0]) {
//Compare passwords
if (bcrypt.compareSync(credentials.password, results[0].password)) {
//Set session data and redirect to restricted area
}
}
});
}
I removed all the error handling here in the example so that its easier to read the code.
1.This works and i am able to login and set the session. But is this all there is to it? Am i missing something?
2.Looks like the salt is prepended to the password when generating hash. Dont I have to save the salt in db?
Any help appreciated
Yes, this is all there is to it! The salt you generate when encrypting the password originally is used to prevent against rainbow table attacks; you do not need to persist it.

Categories