33

We have webpage which uses the -framework to build a . The communication between the browser and the server uses . The interaction to log into the page is the following:

  1. The user opens the website by entering https://myserver.com in the browser
  2. A login dialogue with two form fields for unsername and password is shown.
  3. After entering username and password and pressing the login-button
  4. 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 :

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:

On security.stackexchange are additional informations:

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

HoldOffHunger
  • 18,769
  • 10
  • 104
  • 133
surfmuggle
  • 5,527
  • 7
  • 48
  • 77

5 Answers5

31

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.

Steffen Ullrich
  • 114,247
  • 10
  • 131
  • 172
  • Are you sure, that the referer contains this data if using https? This would mean that this statement `[fields] ... are stripped off of the URL when creating the routing information in the https packaging process by the browser ` omits a very important point. – surfmuggle Oct 31 '14 at 11:25
  • 2
    Yes, these information are kept in the Referer-Header (just try it and watch the requests with developer tools) but this has nothing to do with routing of the https packet. The Referer is inside the HTTP request and will thus be encrypted send to the embedded/linked external sites (like ads, social networks..). But these sites then will see the unencrypted Referer because they are the endpoint of the encryption. – Steffen Ullrich Oct 31 '14 at 11:37
  • `Sending any kind of sensitive data over GET is dangerous,` sending sensitive information over any unsecured channel is dangerous, no matter the "verb". [**POST is not more secure**](https://stackoverflow.com/questions/1008668/how-secure-is-a-http-post) (I know, I know, most of you probably know this already, but I think it's worth repeating until every web dev on Earth sings it) – xDaizu Jan 25 '18 at 16:18
  • @xDaizu If POST over SSL is not any more secure than GET, that implies a GET (over SSL) is fine... – mbrig Jan 26 '18 at 23:05
27

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.

Community
  • 1
  • 1
Bruno
  • 119,590
  • 31
  • 270
  • 376
  • Does anyone know if a browser history entry is made if the get request was fired from javascript as an ajax call? AFAIC [mozilla firefox esr](https://www.mozilla.org/en-US/firefox/organizations/) 24 does not write the userinformation from an ajax get request like this `https://myusername:myPassword@myserver.com/foo/` into the history. – surfmuggle Nov 03 '14 at 19:04
  • AFAIK, XHR requests aren't stored in the history in general. – Bruno Nov 03 '14 at 20:34
0

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.

Mehmet Ince
  • 1,298
  • 9
  • 20
  • Referer headers are normally not passed from HTTPS to HTTP, except when explicitly instructed to do so (which wouldn't make sense on such a page, of course). – Bruno Nov 06 '14 at 12:16
  • Yes you will get an error when you try to get images or javascripts from HTTP web sites but we assume that external domain is under the attacker control, which means attacker can put url HTTPS too. – Mehmet Ince Nov 06 '14 at 12:26
  • It's depends on application. You may have static website or your application may designed to share images between the users. ( Think about that one user can send url to someone else via chat. Receiver can click on that link..) tons of different example can be came across. – Mehmet Ince Nov 06 '14 at 12:36
  • I agree putting the username and password in the query is a bad idea, but I think you're broadening the scope of the question a bit far here. It wouldn't make sense for the user to share their own URL that contain the username and password this way. I was talking about the Referer header, which doesn't apply in the examples you mention. – Bruno Nov 06 '14 at 12:41
0

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

Ironluca
  • 3,402
  • 4
  • 25
  • 32
  • HTTP Basic Authentication is what's used when you type in a URL like `https://myusername:myPassword@myserver.com/foo/`. What you're saying about a second request in response to a 401 being a POST when the first was a GET doesn't really make sense. The browser will retry with the same verb as initially requested. – Bruno Nov 11 '14 at 13:57
0

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.

Jay
  • 353
  • 4
  • 8
  • The only thing about using GET for authentication that I could agree is any more dangerous than POST is the access log files, which should be owned and readable only be root, writable by http web user. If your security practices are sound, there's not reason to not do this. – Jay Feb 06 '19 at 04:18