I'm trying to change a user's password by saving the user document with a password field. I see in Futon that a new hash and salt are created and I can independently verify the hash and salt matches the new password
However when I try to use the new password CouchDB only responds to the old one. I have tried changing the password manually by editing the document in Futon and I get the same behaviour: the hash and salt update but CouchDB does not respond to the new password.
The only means I have found so far to change a password is with Futon's change password facility. Is it not possible to change the password via HTTP or is there a step I'm missing?
Read this: http://wiki.apache.org/couchdb/Security_Features_Overview
Likely you're trying to change admin's password.
User documents that represent server admins do not need to have the
"password_sha" and "salt" attributes defined - their authentication
credentials are stored in the .ini configuration files.
UPD: You can change admin's password via /_config API: http://wiki.apache.org/couchdb/Complete_HTTP_API_Reference#configuration
Related
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.
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.
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
This is a question about generating a token for a user to reset his/her password, without storing said token in the database. This token would be part of a "reset password" URL sent by e-mail.
An answer posted by sudo explains that you can send the user a token with the following information
name
expiration date
hash(secret + user name + expiration date)
The problem with this method is that the user could change his password several times before the token expires. I think this is quite bad because it means that if the user accesses the URL from a shared computer that retains history, anyone could reset our user's password (even if just for a limited amount of time).
So my question is: is it possible to have a token that is usable only once, and that is not stored in the database?
Yes. An easy approach to getting a one-time use token you don't have to store or manage is to offload user management to a microservice like Stormpath where it takes care of all the user management for you-- password reset, password storage, user profiles, authentication, etc.
For password reset here's what it would look like:
User initiates password reset work on a web page
You make API call to stormpath with user's email address or username
Stormpath sends out reset email to user (your "from" address, custom HTML, etc) with a link + token. The reset token that is unique, one-time use, and expires if not used within 24 hours
User clicks on the link and lands on the reset page
You pull the token from the URL and check Stormpath for token verification
User submits new password
Stormpath sends out reset success message (your "from" address, custom HTML, etc)
You can build your own UIs in this flow or use an out of the box, customizale id site (id.mydomain.com) that Stormpath includes.
User never knows Stormpath exists and you don't have to manage or store any passwords or reset tokens.
Full Disclosure - I work at Stormpath
A possible solution is to use a slightly different token:
user name
expiration date
hash(secret + user name + password_hash + expiration date)
When the user accesses the password reset page for the first time, you can retrieve his password hash from the database, and check the hash. It matches, the user can reset his password.
When the user accesses the password reset page for the second time with the same link, it won't work: password_hash has changed, therefore the hash won't match.
But.... There is a problem if the user actually types his original password. In that case password_hash will stay unchanged and the token will remain valid. Because of this edge case, this solution isn't really viable.
What is the most secure way to handle forgotten passwords/password resets? Should I email the password to the user? If so do you then force them to reset it? Or do you let them reset it immediately (without sending an email) and require some other information to verify that it is them? Or is there a better method?
You can't email the password to the user, because you don't know it. You've "hashed" it by applying something like PBKDF2 or bcrypt to it for storage, right?
If you reset the password without confirming it with the owner of the account, an attacker can deny the owner access to his account, at least until he checks his email, by using the victim's email address to request a reset.
A method safe enough for many applications is to email a link to the account owner, containing a large, randomly generated number. This token should only be valid for a limited time. If the owner wishes to reset their password, they click the link and this authenticates them as the account owner. The account owner can then specify a new password.
You shouldn't send passwords via email. Here is a step by step process I've used:
Give users a reset password option.
This option saves a unique token for a user. The token eventually expires (hours, day or days).
A link is emailed to the user which includes the token.
User clicks on the emailed link.
If the token exists and isn't expired, the link loads a new password form. If not, don't load the new password form.
Once the user sets a new password, delete the token and send the user a confirmation email.
Until the new password is set, the old password should remain active. Don't forget to hash and salt the passwords!
I suppose you are going to do it programmatically? Or is it a question for Server Fault?
One of the ways is to send a link to the user's email account. He/she clicks on the link and is redirected to your secure web form where they reset the password.
Do NOT email the password to the user