I have the following situation:
I have a Javascript website where the user need to enter a username and a password and then the site make a ajax call to the Webserver.
On the other site I have a Webserver running PHP which gets the parameters and checks if the username and password is right.
Now my Problem:
How to secure this process e.g: how to secure it if the website does not use https and the user submits his username and password? Is there any algorithm which can do this?
No, this is not possible.
Even if you hash or encrypt the data in the browser before sending it, the algorithm and keys would be public, and the resulting information also can be intercepted and replicated by an attacker.
If you want it to be secure, you need to use HTTPS.
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
While logging on to services of Gmail, Facebook and other sites also, if on performing inspect element and checking the "Preserve Log" box, the password is clearly visible without any encryption in one of the files being sent to the server.
The same doesn't happen when logging into Yahoomail
Why exactly is this occurring? Is it some bug or some programming error? The data being sent to the server is without any encryption. Using tools like WireShark, the passwords can easily be sniffed.
Why, yes, indeed, passwords that you type into a form and then submit that form to the server are in plaintext. By necessity. Because the server needs the plaintext password to authenticate you. Hopefully the connection this plaintext is sent across is HTTPS encrypted, which means no third party can intercept the traffic and see the plaintext. Your browser happens to be able to display the plaintext for you, since, well, it's the originator of the data and a peer in the HTTPS connection.
I don't know what specifically you're doing with Yahoo, but at some point it too will have to send the password to the server in some form or another.
I'm hacking together a script to automate the submission of tickets to our helpdesk system. So far it's a very simple, but working system. I have a page with a form that auto-submits via JavaScript with form value based on the URL requested.
This works great when you access the page from your browser. Assuming you're already authenticated to the ticket system page, the auto-submitted form happily sends its form data and you are directed to the ticket list where you see the newly auto-submitted ticket. Unfortunately of course, the ticket system is an HTTPS secured site, so if you're not logged in you're directed to the login page and the auto-submission fails.
The idea however is to run this auto-submission on a schedule, or kick it off remotely, where the initiator won't necessarily be human and won't be following the form submission to babysit it with delicious authentication cookies.
So, being a newbie in this area, my options seem to be A) dive in and get real messy by listening for the auto-submission response, determine whether the login page is being returned and submit some credentials via JS (not a huge deal as this automation would run solely on a secured server), then resubmit the form... or B) somehow do this the proper way by authenticating beforehand. But that's where my knowledge ends.
I've read through this similar question, but am still coming up short. Is this proper automation only possible if the server in question supports some form of auth token API? Is there not a more direct way to connect and request/submit data to an HTTPS site? I've been glossing over some introductions to cURL, but have not yet dove in.
NB: I don't have direct access to the ticket database, code, nor to the web server processes/accounts running it. I probably can run processes on the same machine, which is why I'm not real concerned with the security of auto-submitting credentials, but that's probably it.
Firstly, whether your ticket system directs you to a login screen if you're not already authenticated has nothing to do with HTTPS - this will be either a username/password <form> that then sets a cookie, or it will be a WWW-Authenticate header. Each of these can be used whether you are using HTTPS or plain HTTP.
Whichever method it uses, if you're planning on doing this in a web browser, chances are you won't be able to because CORS (cross-origin resource sharing) will probably not have been set up to allow it.
If however you're doing this from a script such as Node.js, Python, PHP or anything else that can make arbitrary HTTP(S) requests, you might want to look at a flow like this:
Request the index page of the ticket system
Detect whether it gave you a login screen
If so, fetch any necessary data from the login screen (e.g. a nonce) and make a POST request as if you filled in the username/password yourself
Check that authentication was successful (based on the POST response)
Keep the cookie returned by your POST request and use it to submit the ticket.
For the simpler case where the system uses a WWW-Authenticate header it would be like this:
Request the index page of the ticket system
Detect the WWW-Authenticate header in the HTTP 401 response received
Send an Authorization header with an appropriate value
Check that authentication was successful (based on getting an HTTP 200 instead of a HTTP 401)
Send the same Authorization header again while submitting the ticket.
Using WWW-Authenticate is described at Wikipedia for basic and digest authentication.
Currently, my authentication flow is as follows:
User fills in a login form in the client browser app (AngularJS, to be precise), username and password are stored into the browser's memory (plain Javascript variables).
When accessing protected API resources, the request is authenticated with HTTP Basic Auth over SSL using the credentials stored in memory.
The problem is, when the user refreshes the page, her credentials are wiped out and she needs to sign in again. Am I missing something obvious here?
Few solutions I've found so far:
Store username and password into a cookie: this seems obviously insecure, even when using secure cookies and/or encryption.
Use session cookies: this seems to be against the RESTful principle of statelessness.
(I guess OAuth has the same problem with securely storing access tokens in the client?)
Session cookies are totally fine here. Once installed you dont care of them, browser will send them with each request via headers.
Inspired by this answer, I ended up doing something like this (link opens a rather large picture).
In short, client stores Access Token in a javascript variable, but Refresh Tokens are stored in a server-side session (on the server hosting our client app, not on the API server).
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.