just to know, is it possible to send password through an Ajax request safely?
I've a login box that calls an ajax request to try the login/pass and retrieve a JSON Object with errors (if any).
Should I use a form redirection instead?
[EDIT] Store the encrypted password in the database isn't the solution because the login and password send by ajax are the login / password to access the database itself (internal application).
The only way to send something that can not be intercepted by a third party is by using HTTPS instead of regular HTTP. That way everything sent between the server and the client is strongly encrypted.
For the technical hell of it, you can. If you have access to a one-way cryptographic function crypt(text,key) that supports crypt(crypt(T,A),B) == crypt(crypt(T,B),A) you can do the following:
Have a secret key for your application, KEY. Never tell anyone.
When the user registers, store crypt(password,KEY) in the database.
When the user wants to log in, send them a randomly generated key RAND
The user types the password, the form computes and sends crypt(password,RAND) through unsecure AJAX. The password never leaves the user's computer.
The server computes crypt(crypt(password,RAND),KEY) from the form response, crypt(crypt(password,KEY),RAND) from the database, and compares the two. They should be equal.
All of this is unnecessary complicated an requires a lot of effort to implement correctly and securely. Buying an SSL certificate and using HTTPS is orders of magnitude easier to achieve this level of security, and even more.
Here's what you could do:
Hash Password and store in database
On client side: hash password, then add salt (concatenate session_id string), then hash again
On server: take hashed pw from database, then add salt (concatenate session_id string), then hash again
[Edit: and then compare the hash-salt-hash generated on the server with the one sent from the client]
Intercepting your hash-salt-hash password is quite useless now, because it is only valid for that particular session...
What you're looking for is a "zero knowledge protocol". It is a way of communicating that you know a password without sending it. You would communicate between the javascript running in the user's browser, and the server.
Bonus, these protocols are generally secure even if the connection isn't encrypted. Note that it would be stupid to rely on this and not use SSL, because a man in the middle would simply replace your nice zero knowledge protocol implementation with a look-alike function that just sends the password.
Related
I'm creating a website for some company I work with. It includes user authentification. The database stores the hashed passwords.
At some point on a certain page, the user should be able to sign in via a popup. That requires an asynchronous request to a php file that will request the database with the password.
Which leads me to my question : should I use Javascript to hash the password before it is sent in my asynchronous request, to prevent, for example, man-in-the-middle attacks or things like that ? I don't know if the site will be using HTTPS yet.
Thanks.
Client side hashing can never replace server side hashing. A man in the middle can not only use the "encrypted" password directly as the new password, he can also strip away the JavaScript which encrypts the password. Even worse he could send a copy of the real password to another server, so you would not even recognize the change.
The only option for a website is to use an encrypted HTTPS/SSL connection. There you can send the password plaintext, SSL takes care of secure transport.
Sending hashed passwords isn't going to stop anyone sniffing your connection. The HTTP request contains the hashed pass, which is clearly readable since the request itself isn't encrypted.
If you want to be safe from this sort of stuff, use HTTPS
What is the challenge/response method to securely authenticate with a Server without HTTPS (without sending out password)?
I have an app (Javascript client) that connects over CORS (authenticate) to our backend which in turns will return a token containing the claim (JWT) over non-HTTPS. The REST is stateless so we do token-based and not have session at all.
When the client gets that token, (containing claim) it is added to the header for each request of the client and therefore the backend knows which User Id is doing that request and do the appropriate thing. So far this works for us. My concern is with the authentication process and with the security of each request.
To authenticate the clients sends out email and hashed password pair, however I want to know if there's a more secure way even without using HTTPS for now. I've read to not send the password but do a challenge/response, but what is the implementation of that idea?
And last question would be, even if we get around with the authentication process securely, how about on each request which contains the token with claim can it be secured also?
There is no possible way to do this securely without HTTPS. For your server to authenticate users, you need some kind of token (cookie, adding to requests like you have, etc.) However, the problem is that, without https, an eavesdropper can add javascript to your page. They can then capture the token and use it themself (stealing all the user's data), or modify it. If you want your product to be in any way secure, you need HTTPS.
Edit: I guess you could store some information about the device sending the request (user agent and such), and only allow the token to be used on that device. However, an attacker could just fake the user agent when they reuse the token, so this wouldn't be too hard to bypass.
Challenge response is a mechanism to send passwords in non-clear way.
1°/ client and server must share a cyphering key : best is to manually add certificate on client but could be a little bit heavy. Another solution is to store the key only one time into localStorage.
2°/ client requests a challenge to server : this is a "phrase" generated by server
3°/ client concats its password with this "passphrase", ciphers and send response to server : Challenge => Response
4°/ server decrypt message, search and remove its passphrase to get password.
I am trying to create a secure way for users to log in to and perform certain authorized actions on my custom website. I am trying to have good security without the use of SSL.
At login now, this is what I am trying to improve:
User types in credentials (e-mail and password)
Client browser (JavaScript) one-way-hashes password with SHA-512, sends credential as login-request
Java-based backend receives request, further encrypts the received password-hash(with salt etc) to fit the hashing in the database (which was created on registration), checks for match, and returns a cookie containing a fresh token.
Backend also connects token to user in the database, and the backend will therefore know who future requests is coming from based on this token (without ever sending credentials in the request)
The idea is that if someone manages to pick up such a cookie (or the initial request), it's impossible to get the user's password.
This is great and all, but there's still the problem with repeat-attacks and man-in-the-middle-attacks, when 'bad guys' pick up a request, and uses the token to do stuff on another user's behalf.
By reading up on how to prevent this from happening, I have found that an acceptable method of preventing this could be adding a 'counter' to the token in the cookie, to show how many times the token has been used.
Let's say the cookie initially contains a token and a counter of 0, like this cookie-content: "abc123:0", where the token is abc123, and the counter is 0. It's suggested that the client increment the counter every time a request is made. Let's say a user wants to send a chat-message to another user. The cookie attached to this request will then contain "abc123:1". The backend stores the counter as well as the token, and checks both values. If the received counter is more than the stored counter, awesome. If a 'bad guy' picks up the requests and try to repeat it, the counter will still be 1, and the server will reject it, as the stored counter also is 1(or more).
This sounds great, but I'm not sure how this is any more secure? The 'bad guy' can simply edit the counter-value in the cookie to be 99999 and succeed?
I figured the content of the cookie (the token and the counter) should be hashed in some way, so that the content isn't plain-text. However, the client is HTML/JavaScript; the 'bad guy' can simply check which encryption-method is used, and decrypt it. All scripts are public.
I read something about improving this by sending a one-time 'secret' from the server to the client before the request is made, but I don't see how I can implement this. I guess, on requesting www.example.com/chat, I could generate a random 'secret', and send this to the client, and the client can add this to the cookie when sending a chat-message, or use it as a key, so that an encryption would be more secure, but how would the server know the secret upon receiving the request? How can the server reverse this? The server has to know the secret when decrypting it, so where should it be stored? Plain-text in the cookie next to the hash? Then the 'bad guy' can do the same thing. In the database? Upon requesting www.example.com/chat, should the backend know WHO is requesting it, so that it can be stored in the database along with that user? In that case, how should the backend authenticate the user, to be sure that there's not a man-in-the-middle or repeat-attack requesting /chat?
What is this method of security called, and is it possible to use it for what I need (with HTML/JavaScript)? If not, what are my options, beside SSL?
It's called bad security that does not rely on trust.
The client needs to fully trust the server, otherwise everything - including the page that is used to enter the password - cannot be trusted. Currently the only way of establishing trust is the certificate store that is provided within the browser (you should be able to trust the browser!). And the only software that is able to use it across browsers is SSL/TLS.
I am currently creating a small chat application on node.js using mongojs, I have a mongo collection of users with a username, password and name fields. The application uses socket.io to send the data real time and then authenticating the user and letting him use the application if the auth is correct.
However, I don't want to send the password on plain text, is there any way of encrypting the password on the client side? Or any better way to do this? I have thinking of using this on a separate page, but I need to do this on Single page.
Here is my client side code:
function loginUser(){
console.log("Login User");
username = $('#login-username').val();
password = $('#login-password').val();
//VALIDATIONS
socket.emit('auth-user', {"username": username, "password": password});
return false;
}
I would strongly recommend against client-side encryption of your passwords.
If you are hashing before the password is sent, then you will have to store the hash of their password as is (or you could hash it again, which is equally useless). But unless you set up a public/private key system to decrypt them server-side, then RE-hash them with a separate hashing algorithm, then you will have absolutely zero added benefit.
I do not know of any major sites that encrypt client side, because the accepted norm is to use HTTPS, since it allows ALL of your outgoing data to be encrypted, by being sent on top of SSL/TCP protocol.
It's important to note that socket.io is not insecure, as you seem to be assuming it is; it follows basic internet protocol, and will be equally as safe as any other site's login that isn't using https. Just something to consider.
Hmm... Very good question. I have never used socket.io with authentications before.
But it seems like passport, passport for socket.io, is the Socket IO's preferred way of handling authentication based on their wiki. I wasn't able to find anything about whether passport is encrypting the data, but it is at least using the POST call.
At the end of the
We are developing an application that requires serious security. Now, my problem is that client enters a password, and that password should be sent to another client in an email. The key point here is that even the server should not see the password, so the client must send the email directly to another client through the application using client-side stuff.
If you want to transfer the Data from one client to another by email you must go through a server. In this situation what I recommend is encoding the password with a key that only the clients have access to, thus making it unreadable to the server. Or having the key stored on a different server.
You will need an email server that you can install on the client.
There are several Python based email servers. FreeSMTP is easy to install and configure but is only free for 10 emails per day - but certainly easy to get going for proof of concept.
Finally you will need to talk to the email server from your client code. It is not clear from your question whether you client is Flex or JavaScript. If you are using Flex, then SMTPMailer might help. http://code.google.com/p/smtpmailer/. It might not be possible to do this with JavaScript - see Javascript IMAP and SMTP client?.
The concept doesn't seem to be a good one though. Instead can you send a non reversible hash derived from the password - then the server will never see the password - but the hash may still be useful for authentication purposes.