Using your own credentials in Nodejs app, is it safe? - node.js

is it save to upload your nodejs application that uses your own credentials to login?
Edited : I am using my password and username -I am storing them in json file and reading form this file- to login into my account in an automated way, is it save to host this app or this will be threaten my privacy?

You should avoid storing your password anywhere, you could commit your code to Github with the password (very common) and your password could be publicly available, also you need to be able to trust the place you are going to be hosting your server. You should make use of something like Azure Key Vault for storing your passwords if you are using Azure. If your application has to have the password stored then have it hashed and salted, revealing of the hash and salted password will not be as bad as revealing your password.

You should never store username and password in the JSON file as you will pushing the code to GitHub or bitbucket. Storing password will be very much vulnerable. Instead of that you can store encrypted version of password or you can use database for storing username and password.

If you mean storing username & password for the last user that logged-in, the common approach is storing a token in the app.
I'm guessing you are logging in to an online service that you coded:
For instance login through the app to the server, get a token in exchange, next time for auto login instead of username & password send that token, if token still valid (time limit, or login from another location should change/delete token in the server) then the server should respond you as you are logged in.
If it is something else;
Like an offline app, but that still requires a login, if they create a user account in the app;
a) Hash user's password with an encryption library something like CryptoJS https://github.com/brix/crypto-js
But remember do not bundle password with the app, on first launch ask for password then store it. So you can avoid accidental password share.
From docs:
var CryptoJS = require("crypto-js");
// Encrypt
var ciphertext = CryptoJS.AES.encrypt('my message', 'secret key 123').toString();
// Decrypt
var bytes = CryptoJS.AES.decrypt(ciphertext, 'secret key 123');
var originalText = bytes.toString(CryptoJS.enc.Utf8);
console.log(originalText); // 'my message'
b) just make the app remember username only, make the user use the password.
What you are going to follow depends on what are you trying to achieve and how your app works.

Related

reset password putting password into jwt payload

My one time reset password link is like this with a token http://url.com/token. The payload of the token contains a password (hashed)
When the user request forgot password, then this token is generated like this
jwt.sign({ password, email }, secret, {expiresIn: "1d"})
When the user clicks the link and fills out the reset form. The password reset request is sent to the server and in the body contains the token from the url and the new password.
jwt.verify(req.body.token, secret)
Then I just checked if the hashed password in the database matches the one shown in the jwt payload. If it does, I will change the password in the database. If it doesnt,the one time link has been used already so I error (returns 400 error).
How to do this without storing password?
I would definitely refrain from sending the old password hash in the JWT. If someone were to get access to a bunch of these, they could use them to try to brute-force hack your authentication.
What I would do is have a separate table for password reset requests. So every time someone asks for a reset link
You create a new password reset request entry in your DB with the reset token
If there already was an existing password reset request for that user in your DB, you delete it
The user submits the reset request with their new password and the token
You query your password reset request table and verify that the token they provided matches the token in your DB (i.e. because you only keep the most up-to-date one, you know that it is the correct one)
You action the password change and delete the password reset request from the DB
Good luck!
People can try to crack a password hash even if it takes a long time:
https://security.stackexchange.com/questions/199494/how-to-crack-a-password-given-its-hash-and-its-possibilities
This makes your password hash sensitive which means you should not put it in your JWT token.
https://stackoverflow.com/questions/43496821/is-it-safe-to-store-sensitive-data-in-jwt-payload#:~:text=Ideally%20you%20should%20not%20store,by%20simply%20base64%20decoding%20it.
The time complexity/security risk depends on a lot of things(be sure you are salting your password).
This is a common problem with JWT tokens:
Here is a link to some solutions:
Invalidating JSON Web Tokens
One that was missed would be adding a password version(some number that increments when the password is changed) to your password. Then passing this version back in your token, instead of the password hash. Since you are already querying your database(to make sure the password is the same) you can just query to make sure the password version is the most recent version without any extra time complexity. If it is the same change the password. If it is not the same do not change the password.

Most secure way to temporarily store a password

I have the following use case:
My web application is used for creating prescriptions. When I send the prescription creation request to the government API it is signed with the current user's certificate. The certificate is stored on the application server and is encrypted with a password which only the user knows.
Users want to be able to store their password in my app temporarily so that they don't need to paste it in for each prescription they create.
What would be the most secure way to store this password? Couple of ideas:
Local storage in the browser.
Bad because anyone with an access to the user's device can see the
password even if they're not logged in. Also if the app is not running I have no way to clear the password if the desired storage time expires.
Frontend app memory.
Bad because if user refreshes the page or opens another tab the stored password is gone.
Backend, in database
This sounds like the best option because I can encrypt the password. Is it even worth encrypting though? I would have to encrypt it with some key stored on the same machine so if someone gains access to this machine the encryption doesn't matter because they would be able to decrypt it quite easily.
Separate the password encryption key and the encrypted password:
Generate and store a random key (and nonce / salt)
Encrypt the password (e.g. AES-256-GCM) with the random key
Store the encrypted password on your backend
Send the random key with the request to temporarily decrypt the password
Delete the encrypted password on the backend when the session expires
That way:
The random key stored in the browser can only be used within the current user session and is useless on its own
The encrypted password on your backed can only be used with the random key stored in the browser and is useless on its own

Tokenised Login System - The Correct Way?

So I want to have a play with making a tokenised login system but wanted to get my head around some of the nitty gritty. Please don't go and tell me to use OAuth etc as that isn't what I'm trying to achieve.. I want to understand the best way of how they work.
So this is the basic understanding of how I'd see the system working:
User registers on their phone application, which sends the username and password to a server via HTTPS. The server then generates two tokens, a public token and a private token which are both returned to the client.
The client then stores both of these tokens locally using localstorage.
So for subsequent page requests that need authentication, the client will send the public token and a hashed version of the private token to the server.
The server checks the database for the public token, unhashes the hash that was sent to the server, using something like timestamp and compares them. If both match, then the user is authenticated.
Now this fine, I understand that this should in theory be pretty secure from the point of view that the private token is only transmitted the once, ever over HTTPS so the chances of someone getting hold of it and authenticating as the user are minimal.
Now comes my real question on security... how can you protect user authentication if someone were to hack access to your database only (assuming the database isn't on the same server as the server side code). If I were to login and get the database then I'd have username,encrypted password,public and private tokens. I could technically then use these two tokens to authenticate myself as the user. What's the way to avoid this?
Hope that made sense!
Update
Okay, so is this process secure enough:
User registers by sending username and password over HTTPS.
The password uses bcrypt and is stored in the database
User comes to login and enters their username and password
The password is checked throug bcrypt against the one stored in the database
If there is a match, a JWT is generated using a secret key and sent back to the client
All future authentications that contain this token are verified against the secret key and if they match, the user is authenticated.
All of the above would be over HTTPS.
Is that secure enough? Cuts out the issue of having the token stored on the server as it would only be stored on the clients system and also the passwords are hashed in the database if that were to be leaked.

How to verify a password against a database on a remote server?

We are building an api that helps third party apps verify UID/password combinations against a database on a remote server.
When a user enters his username and password in the third party app and hits submit, the username and password have to be sent over to our api securely, we take the UID and password, send it over to a remote server that compares it against the database and tells us if the combination is valid or not. How do we send the password? How do we hash it so that it can be un-hashed and verified by the remote server that has the database?
We are using the django rest framework.
First you want to use a strong SSL connection.
Second you can use a salt like "mysecretsalt$"§%§$%§$" and hash it like
$var = sha1($salt.$pass);
Then send $var as authtoken.
On the remote Server you save all salted password on your database and compare that with the token or just salt it when ever it is requested and compare the salted password from the database with the sent token...
As long as you use SSL for all network communication, there's no need to "pre-hash" it. Just send it along.
Anything else you do (encryption, etc) is just going to poorly re-invent SSL anyway, so just do it.

How can I secure online API for my app?

I'm creating an app for Windows Phone and Android. So right now Im building a webapi they both can use, but I want to secure it som non other then my applications can use it. How do I go about it? No one else then my apps is going to access these APIs.
I don't want to implement OAuth.
I've got two scenarios that I'm thinking of:
First (I store username and hashed password on the client):
basic-auth over https/ssl, thats it.
Second (I store accesstoken on the client):
basic-auth over https/ssl to receive a access token.
to get access token, user sends a request for requestoken a token that verifies that both the client and server knows the clientsecret.
for each call to the API the accesstoken has to be sent with to check access
The problem as I see the second approach is that the server sends accesstoken to the client, if anyone where to get this they would have the access of the user.
How is it done in the real world?
You could use a slight modification of First:
store username and password on client
basic-auth over https
Storing a password hash on the client, then sending the hash and comparing it with the hash in the database is equivalent to storing a plain text password in the database because the hash becomes the password. So, your apps should authenticate with a username and password like any human user would do.
But your concerns for the second approach apply too. If somebody intercepts the message, he has your credentials.
A more secure solution is HMAC authentication (now we're talking "real world").
a user has a secret key that is stored on server and client
each request gets canonicalized (transformed into a distinct string, which contains the request method, URI, parameters and timestamp)
the canonicalized request gets hashed with HMAC using the secret key, hash and user id are passed in the HTTP Authorization header
on the server, a hash is generated using the same algorithm (with timestamp from the HTTP Date header) and compared with the sent hash.
if the results are equal, the request is authenticated
An example is the Amazon S3 REST API - the linked documentation is also a good example how to implement it for your own API.

Resources