Difficulty in understanding login mechanism password security? - security

In our login page we enter username password and then submit the form. The password goes to the server where it is crypted using some algorithm and then saved to database. But when it is posted to the server it can be seen in firebug post data. So how is it secure i have seen the similiar implementation in other cases as well. Can not it be trapped in between the time it is taken from client to server.

Firebug can see the password because it is acting as a proxy on your client (one of the two endpoints of the communications path). SSL/TLS (https) encrypts the data in transit between the two endpoints (think of it as a protected tunnel where the only way to see the real data inside is to be at one of the endpoints). Since Firebug runs on the client, it has access to the endpoint, where the data is not encrypted. Think of a tunnel you can pass data into that will be protected in transit; Firebug sits at the entrance to that tunnel so it can see everything that goes in (and comes out).
At a minimum, sending passwords (and any other sensitive data) should be done over SSL/TLS, to prevent someone/something not on an endpoint of the tunnel from seeing the data. Ideally, you will want to run everything over https to prevent session hijacking attacks (you can read all about that in the Wikipedia summary). Any site not encrypting at least the exchange of credentials (passwords, etc) is not following industry best-practices and should be considered an insecure implementation.

yes, you are right. If data is sent in clear text to the server, it can be captured in Transit. Hence, always use HTTPS connection.

Related

Are security concerns sending a password using a GET request over https valid?

We have webpage which uses the sapui5-framework to build a spa. The communication between the browser and the server uses https. The interaction to log into the page is the following:
The user opens the website by entering https://myserver.com in the browser
A login dialogue with two form fields for unsername and password is shown.
After entering username and password and pressing the login-button
an ajax-request is send using GET to the URL: https://myusername:myPassword#myserver.com/foo/bar/metadata
According to my understanding using GET to send sensitive data is never a good idea. But this answer to HTTPS is the url string secure says the following
HTTPS Establishes an underlying SSL conenction before any HTTP data is
transferred. This ensures that all URL data (with the exception of
hostname, which is used to establish the connection) is carried solely
within this encrypted connection and is protected from
man-in-the-middle attacks in the same way that any HTTPS data is.
An in another answer in the same thread:
These fields [for example form field, query strings] are stripped off
of the URL when creating the routing information in the https packaging
process by the browser and are included in the encrypted data block.
The page data (form, text, and query string) are passed in the
encrypted block after the encryption methods are determined and the
handshake completes.
But it seems that there still might be security concerns using get:
the URL is stored in the logs on the server and in the same thread
leakage through browser history
Is this the case for URLs like?
https://myusername:myPassword#myserver.com/foo/bar/metadata
// or
https://myserver.com/?user=myUsername&pass=MyPasswort
Additional questions on this topic:
Is passsing get variables over ssl secure
Is sending a password in json over https considered secure
How to send securely passwords via GET/POST?
On security.stackexchange are additional informations:
can urls be sniffed when using ssl
ssl with get and post
But in my opinion a few aspects are still not answered
Question
In my opinion the mentioned points are valid objections to not use get. Is the case; is using get for sending passwords a bad idea?
Are these the attack options, are there more?
browser history
server logs (assuming that the url is stored in the logs unencrypted or encrypted)
referer information (if this is really the case)
Which attack options do exist when sending sensitive data (password) over https using get?
Thanks
Sending any kind of sensitive data over GET is dangerous, even if it is HTTPS. These data might end up in log files at the server and will be included in the Referer header in links to or includes from other sides. They will also be saved in the history of the browser so an attacker might try to guess and verify the original contents of the link with an attack against the history.
Apart from that you better ask that kind of questions at security.stackexchange.com.
These two approaches are fundamentally different:
https://myusername:myPassword#myserver.com/foo/bar/metadata
https://myserver.com/?user=myUsername&pass=MyPasswort
myusername:myPassword# is the "User Information" (this form is actually deprecated in the latest URI RFC), whereas ?user=myUsername&pass=MyPasswort is part of the query.
If you look at this example from RFC 3986:
foo://example.com:8042/over/there?name=ferret#nose
\_/ \______________/\_________/ \_________/ \__/
| | | | |
scheme authority path query fragment
| _____________________|__
/ \ / \
urn:example:animal:ferret:nose
myusername:myPassword# is part of the authority. In practice, use HTTP (Basic) authentication headers will generally be used to convey this information. On the server side, headers are generally not logged (and if they are, whether the client entered them into their location bar or via an input dialog would make no difference). In general (although it's implementation dependent), browsers don't store it in the location bar, or at least they remove the password. It appears that Firefox keeps the userinfo in the browser history, while Chrome doesn't (and IE doesn't really support them without workaround)
In contrast, ?user=myUsername&pass=MyPasswort is the query, a much more integral part of the URI, and it is send as the HTTP Request-URI. This will be in the browser's history and the server's logs. This will also be passed in the referrer.
To put it simply, myusername:myPassword# is clearly designed to convey information that is potentially sensitive, and browsers are generally designed to handle this appropriately, whereas browsers can't guess which part of which queries are sensitive and which are not: expect information leakage there.
The referrer information will also generally not leak to third parties, since the Referer header coming from an HTTPS page is normally only sent with other request on HTTPS to the same host. (Of course, if you have used https://myserver.com/?user=myUsername&pass=MyPasswort, this will be in the logs of that same host, but you're not making it much worth since it stays on the same server logs.)
This is specified in the HTTP specification (Section 15.1.3):
Clients SHOULD NOT include a Referer header field in a (non-secure) HTTP request if the referring page was transferred with a secure protocol.
Although it is just a "SHOULD NOT", Internet Explorer, Chrome and Firefox seem to implement it this way. Whether this applies to HTTPS requests from one host to another depends on the browser and its version.
It is now possible to override this behaviour, as described in this question and this draft specification, using a <meta> header, but you wouldn't do that on a sensitive page that uses ?user=myUsername&pass=MyPasswort anyway.
Note that the rest of HTTP specification (Section 15.1.3) is also relevant:
Authors of services which use the HTTP protocol SHOULD NOT use GET based forms for the submission of sensitive data, because this will cause this data to be encoded in the Request-URI. Many existing servers, proxies, and user agents will log the request URI in some place where it might be visible to third parties. Servers can use POST-based form submission instead
Using ?user=myUsername&pass=MyPasswort is exactly like using a GET based form and, while the Referer issue can be contained, the problems regarding logs and history remain.
Let assume that user clicked a button and following request generated by client browser.
https://www.site.com/?username=alice&password=b0b123!
HTTPS
First thing first. HTTPS is not related with this topic. Because using POST or GET does not matter from attacker perspective. Attackers can easily grab sensitive data from query string or directly POST request body when traffic is HTTP. Therefor it does not make any difference.
Server Logs
We know that Apache, Nginx or other services logging every single HTTP request into log file. Which means query string ( ?username=alice&password=b0b123! ) gonna be written into log files. This can be dangerous because of your system administrator can access this data too and grab all user credentials. Also another case could be happen when your application server compromise. I believe you are storing password as hashed. If you use powerful hashing algorithm like SHA256, your client's password will be more secure against hackers. But hackers can access log files directly get passwords as a plain-text with very basic shell scripts.
Referer Information
We assumed that client opened above link. When client browser get html content and try to parse it, it will see image tag. This images can be hosted at out of your domain ( postimage or similar services, or directly a domain that under the hacker's control ) . Browser make a HTTP request in order to get image. But current url is https://www.site.com/?username=alice&password=b0b123! which is going to be referer information!
That means alice and her password will be passed to another domain and can be accessible directly from web logs. This is really important security issue.
This topic reminds me to Session Fixation Vulnerabilities. Please read following OWASP article for almost same security flaw with sessions. ( https://www.owasp.org/index.php/Session_fixation ) It's worth to read it.
The community has provided a broad view on the considerations, the above stands with respect to the question. However, GET requests may, in general, need authentication. As observed above, sending user name/password as part of the URL is never correct, however, that is typically not the way authentication information is usually handled. When a request for a resource is sent to the server, the server generally responds with a 401 and Authentication header in the response, against which the client sends an Authorization header with the authentication information (in the Basic scheme). Now, this second request from client can be a POST or a GET request, nothing prevents that. So, generally, it is not the request type but the mode of communicating the information is in question.
Refer http://en.wikipedia.org/wiki/Basic_access_authentication
Consider this:
https://www.example.com/login
Javascript within login page:
$.getJSON("/login?user=joeblow&pass=securepassword123");
What would the referer be now?
If you're concerned about security, an extra layer could be:
var a = Base64.encode(user.':'.pass);
$.getJSON("/login?a="+a);
Although not encrypted, at least the data is obscured from plain sight.

Sanity Check: SSL+ POST vs. un-encrypted GET

A classic dumb thing to do is pass something security related info via a GET on the query string ala:
http://foo?SecretFilterUsedForSecurity=username
...any yahoo can just use Fiddler or somesuch to see what's going on....
How safe is it to pass this info to an app server(running SSL) via a POST, however? This link from the Fiddler website seems to indicate one can decrypt HTTPS traffic:
http://fiddler2.com/documentation/Configure-Fiddler/Tasks/DecryptHTTPS
So is this equally dumb if the goal is to make sure the client can't capture / read information you'd prefer them not to? It seems like it is.
Thanks.
Yes, it's "equally dumb". SSL only protects data from being read by a third party; it does not prevent the client (or the server) from reading it. If you do not trust the client to read some data, they should not be given access to that data, even just to make a POST.
Yes, any user can easily examine the data in a POST request, even over HTTPS/SSL, using software like Burp Suite, Webscarab, or Paros Proxy. These proxies will complete the SSL transaction with the server, and then pass on the data to the client. All data passing through the proxy is stored and is visible to the client.
Perhaps you are trying to store sensitive/secret data on the client-side to lighten the load on your server? the way to do this so that the user cannot look at it (or change it) even with a proxy, is to encrypt it with a strong symmetrical secret key known only to the server. If you want to be sure that the encrypted data is not tampered with, throw on an HMAC. Make sure you use a sufficiently random key and a strong encryption algorithm and key length such as AES 256.
If you do this you can offload the storage of this data to the client but still have assurance that it has not changed since the server last saw it, and the client was not able to look at it.
This depends on who you're trying to protect your data from, and how much control you have over the client software. Fundamentally, in any client-server application the client must know what it is sending to the server.
If implemented properly, SSL will prevent any intermediary sniffing or altering the traffic without modifying the client. However, this relies on the connection being encrypted with a valid certificate for the server domain, and on the client refusing to act if this is not the case. Given that condition, the connection can only be decrypted by someone holding the private key for that SSL certificate.
If your "client" is just a web browser, this means that third parties (e.g. at a public wi-fi location) can't intercept the data without alerting the person using the site that something is suspicious. However, it doesn't stop a user deliberately by-passing that prompt in their browser in order to sniff the traffic themselves.
If your client is a custom, binary, application, things are a little safer against "nosy" users: in order to inspect the traffic, they would have to modify the client to by-pass your certificate checks (e.g. by changing the target URL, or tricking the app to trust a forged certificate).
In short, nothing can completely stop a determined user sniffing their own traffic (although you can make it harder) but properly implemented SSL will stop third-parties intercepting traffic.
The other, more important reason not to add confidential information into URL with GET requests is that the web server and any proxies on the way will log it. POST parameters don't get logged by default.
You don't want your passwords to show up in server logs - logs are usually protected much, much less than, for example, the password database itself.

Node.js TCP socket sessions

I have multiple clients connecting to a Node.js TCP socket server from an app. I would like to know a secure way of managing their session.
Username + password is passed over the socket to the server. The server confirms this is correct.
I believe that I now need to generate a unique token to send back to the client.
Now if the user closes the app, then opens it again, this token can be passed to the server and thus the server will confirm the user is authenticated again.
Potentially though, this token could be used by somebody else to gain access to this persons account. Is there a way to prevent this?
Is there a more secure way (whilst still maintaining the ability for the user to authenticate without logging in again)?
How would you handle connections from other devices using the same login. Do they get a different token or the same token?
Many thanks.
It comes down to your definition of secure enough. What you're doing now, which is essentially session tracking, and it is generally secure enough for a lot of general purpose usages - however there is typically an extra component added in which is a session should only be considered valid for a particular ip. If the users' IP changes, you should make them login again and issue them a new token. That way if some bad guy hijacks their session id it won't do them any good.
Now of course this is only valid if your bad guy can't appear to come from the same IP address as your client. If you are concerned about bad guys who are behind the same NAT as your client, and thus can appear to come from the same IP, then you'll have to bump up your security a bit more and maybe consider a system similar to what SSH uses, but that's a bit more complex.
As for connections from multiple devices, it's up to you - you can either keep track of some single token and just hand back that token when the user logs in from a different IP (while at the same time now allowing both IPs to access the site using that same token), or you can just issue a fresh token every time someone authenticates. Personally I tend to find issuing fresh tokens easier, much less tracking and hassle... but it comes down to your application and how you want to organize things, I could dream up good use cases for both methods.
Also, as for doing the password exchange.. You should at least do some hashing there, ie, server sends client some random_string, client then uses some hash function (such as md5 or sha) to compute hash(random_string + hash(username + password)) and sends it back. The server then verifies that this matches by checking hash(random_string + password_hash) is equal to whatever the user sent it. This makes it so the user's plain text password never has to be stored anywhere - on the server you just store password_hash = hash(username+password) when the password changes.
Maybe something like this:
FIRST LOGIN:
username + pwd (hashed) ---> check user/hashed pwd
receive token <--- send token
NEXT LOGIN:
request login ---> receive request
receive random string <--- send random string
hash string with token as salt ---> compare hashed string
You should allow only one attempt with that random string and if possible check the IP from the original login.
This is not perfect because you could still intercept the token at login, but then you would also have the username and pwd.
This question basically comes down to session hijacking using stolen cookies. So the question is how you can secure the cookie as good as possible.
Use https instead of http and force your users to use https. This way, the cookie is not transmitted as clear text and can not be stolen using eavesdropping.
Set the secure attribute on cookies (see Wikipedia) to bind the cookie to https and avoid it from being transferred via http.
Use some kind of message authentication digest, such as HMAC, to make sure that the cookie has not been tampered.
Optionally you can embed the client's IP address into the cookie and only accept it if it is being sent from the specific IP. Unfortunately this may cause problems with proxy servers or dial-up connections where IP addresses are newly assigned from time to time.
Last but not least allow one token only to be used once at a given point in time. If the user logs on using the same token on a second machine, either disallow the connection or end the first machine's session.
Hope this helps ...
PS: I am very sorry, I skipped the TCP part. Of course most of what I wrote only applies to http, not TCP. Anyway, some things might help anyway, such as #3, #4 and #5.

Username and password in https url

Consider the URL:
https://foo:password#example.com
Does the username/password portion in the above example qualify as a "URL parameter", as defined in this question?
When you put the username and password in front of the host, this data is not sent that way to the server. It is instead transformed to a request header depending on the authentication schema used. Most of the time this is going to be Basic Auth which I describe below. A similar (but significantly less often used) authentication scheme is Digest Auth which nowadays provides comparable security features.
With Basic Auth, the HTTP request from the question will look something like this:
GET / HTTP/1.1
Host: example.com
Authorization: Basic Zm9vOnBhc3N3b3Jk
The hash like string you see there is created by the browser like this: base64_encode(username + ":" + password).
To outsiders of the HTTPS transfer, this information is hidden (as everything else on the HTTP level). You should take care of logging on the client and all intermediate servers though. The username will normally be shown in server logs, but the password won't. This is not guaranteed though. When you call that URL on the client with e.g. curl, the username and password will be clearly visible on the process list and might turn up in the bash history file.
When you send passwords in a GET request as e.g. http://example.com/login.php?username=me&password=secure the username and password will always turn up in server logs of your webserver, application server, caches, ... unless you specifically configure your servers to not log it. This only applies to servers being able to read the unencrypted http data, like your application server or any middleboxes such as loadbalancers, CDNs, proxies, etc. though.
Basic auth is standardized and implemented by browsers by showing this little username/password popup you might have seen already. When you put the username/password into an HTML form sent via GET or POST, you have to implement all the login/logout logic yourself (which might be an advantage and allows you to more control over the login/logout flow for the added "cost" of having to implement this securely again). But you should never transfer usernames and passwords by GET parameters. If you have to, use POST instead. The prevents the logging of this data by default.
When implementing an authentication mechanism with a user/password entry form and a subsequent cookie-based session as it is commonly used today, you have to make sure that the password is either transported with POST requests or one of the standardized authentication schemes above only.
Concluding I could say, that transfering data that way over HTTPS is likely safe, as long as you take care that the password does not turn up in unexpected places. But that advice applies to every transfer of any password in any way.

Securing parts of an HTTP request?

How does one go about securing parts of an HTTP request, say their Session ID? I know you can use HTTPS, but then your servers must decrypt all of the request. Wouldn't it be ideal to only encrypt the required parts of a request?
Are there any frameworks or resources out that that allow you or inform you how to do this?
HTTPS is the correct tool to use. The computational load of decrypting the packets is very low. Google changed to HTTPS by default for the whole of GMail earlier this year, and they report that the CPU load on their servers for SSL encryption/decryption is around 1%.
If you only encrypt part of the stream then you still have the problem of man-in-the-middle and replay attacks. SSL is the only way to prevent these. It doesn't really matter if the session ID is encrypted. If a man-in-the-middle can capture it, he can reuse it in it's encrypted form, and the server wouldn't know the difference.
Here's a blog post about Google's experience since the GMail switch to 100% SSL.
HTTPS is all or nothing. If not all elements on a page are secured with HTTPS then users will get usually get a "broken lock" in the upper left corner. This is because an attacker could use this to inject an attack similar to xss and obtain the document.cookie value.
Further more if 1 request is sent with a session id then an attacker can obtain the value and authenticate as you.

Resources