I'm setting up a home HTTP server which can send and receive JSON data to/from different clients (Android and iPhone apps).

I'd like to allow access only to certain users and I'm considering using a simple username/password mechanism, as setting up client certificates seems a bit of an overkill for this small project.

Of course I can't send clear passwords from the client to the server on plain HTTP, otherwise anyone with wireshark/tcpdump installed could read it. So, I'm thinking about the following mechanism:

  1. The HTTP server can be set up as HTTPS server
  2. The server also has username/password database (passwords might be saved with bcrypt)
  3. The client opens the HTTPS connection, it authenticates the server (so a server certificate is needed) and after exchanging the master key, the connection should be encrypted.
  4. The client sends the username/password in clear to the server
  5. The server runs bcrypt on the password and compares it with the one stored in the database

Is there any problem with this kind of configuration? The password should be safe since it's sent on an encrypted connection.

  • 6
    Just to add to the answers you've received already, in this kind of set-up I'd recommend looking at Certificate Pinning which helps mitigate MITM attacks... – Rory McCune Aug 4 '14 at 15:12
  • Maybe consider hashing the password instead of (or in addition to) encrypting it. – user541686 Aug 7 '14 at 2:53
  • Even though it might be safe if you use https. One problem which I read in other questions is that the username & password will get written to the server logs if it's directly passed in the urls. It can be dangerous if the logs security get compromised. – Krishnadas PC Aug 25 '17 at 3:00

Yes, this is the standard practice. Doing anything other than this offers minimal additional advantage, if any (and in some cases may harm the security). As long as you verify a valid SSL connection to the correct server, then the password is protected on the wire and can only be read by the server. You don't gain anything by disguising the password before sending it as the server can not trust the client.

The only way that the information could get lost anyway is if the SSL connection was compromised and if the SSL connection was somehow compromised, the "disguised" token would still be all that is needed to access the account, so it does no good to protect the password further. (It does arguably provide a slight protection if they have used the same password on multiple accounts, but if they are doing that, they aren't particularly security conscious to begin with.)

As MyFreeWeb pointed out, there are also some elaborate systems that can use a challenge response to ensure that the password is held by the client, but these are really elaborate and not widely used at all. They also still don't provide a whole lot of added advantage as they only protect the password from being compromised on an actively hacked server.

  • 5
    @AJHenderson +1, having the client send the hash would definitely be bad, as the point of the authentication protocol is to ensure that the visitor knows the correct password, not the correct password hash. If a malicious party could obtain the hash (stolen password database, man in the middle, whatever) and the system relied on the visitor sending the hash instead of the password, any notion of real security would be out the window. – Craig Aug 4 '14 at 20:04
  • 8
    There is sometimes benefit to hash at client and then hash some more at the server. This can help ensure the password is obfuscated in any clear text logs at the client, server, and on the network. – Andy Boura Aug 5 '14 at 7:41
  • 2
    @Craig Letting the client compute the expensive salted hash is perfectly fine, as long as you apply a cheap unsalted hash on the server before storing it (or some other kind of one way function, like modular exponentiation). – CodesInChaos Aug 5 '14 at 12:29
  • 2
    @CodesInChaos - Because nothing client side is trusted. An attacker can skip the entire slow process by bypassing the client entirely. You need to make sure you can't build a rainbow table of cheap, fast hash values. It isn't feasible if you salt each and provided the intermediate hash is long enough. Otherwise, you just make a rainbow table of hash values which can be generated at a very, VERY fast rate if they are cheap. – AJ Henderson Aug 5 '14 at 14:08
  • 2
    Also, while we're talking issues like POST vs GET, be sure to implement forward secrecy so your secure sessions can't be decrypted later on by somebody who obtains your server's private key. – Craig Aug 5 '14 at 16:20

Not necessarily.

You also need to ensure the following:

  1. Your site is protected against cross-site request forgeries. Use Synchronizing Token Pattern.

  2. Your site is protected against session fixation attacks. Change session id on login.

  3. If using session cookies, that your entire site is HTTPS, not just the login URL, and that your session cookie is marked as secure and http only (no JavaScript access). Browser will send session cookie unencrypted if user types http://yoursecuresite (in same browser session).

  4. You are using a recent protocol. SSL 1 and 2 are broken, and 3 might be too. Try to use TLS 1.3.

  5. You are using a strong cipher.

  6. You are not using HTTP compression (GZip) or TLS compression. If your site displays user input (like a search input), then I can figure out your CSRF tokens and bank account number if you're using compression.

  7. Your server does not allow insecure client re-negotiation.

  8. You are using a 2048-bit RSA key (or the equivalent for an EC key), and that no one else knows your private key.

  9. You are using HSTS so browser goes direct to https even if user types http

  10. You are using perfect forward secrecy so your historical communications are secure even if your private key is leaked

  • if the entire site is https, do I Still need cookie marked as secure? They would still be encrypted "for free" due to the TLS layer, right? – Emiliano Aug 4 '14 at 22:11
  • 2
    Can you explain point 6? Why compression would make the connection less secure? – Emiliano Aug 4 '14 at 22:13
  • Ya you still want secure cookie, http only, as its still stealable if not. See xss. Compression kills encryption. See BEAST and CRIME attacks. – Neil McGuigan Aug 4 '14 at 23:17
  • 2
    @Emiliano: even your site is HTTPS only, an attacker can setup a man in the middle attack and setup a fake server that uses plain HTTP, performing what is known as SSL stripping. The browser will send to the fake server the user's cookie. To mitigate this, you need Secure cookie and HSTS policy. – Lie Ryan Aug 5 '14 at 0:01
  • 9. Employ PFS to mitigate the risk of somebody (for example some evil government) stealing your private keys. – FooF Aug 5 '14 at 12:12

As long as you verify the certificate validity, this is perfectly fine and is done all the time.


Most of the sites usually considered to be secure take pretty much the approach you are describing. Or put differently, you have simply described established industry standard.

I would recommend against using an approach less secure than the one you mention. (Whether bcrypt is better or worse than other salted hashes is a discussion I won't be going into. Just don't use anything weaker than a salted hash.)

If you want to distinguish yourself as having security above established industry standards, there are other options available. But it takes a huge effort in all areas of your application to make it worthwhile.

Areas regarding password validation that could be more secure include:

  • Protecting the server against DoS attacks by offloading most of the computation during validation to the client. I.e. don't iterate hashing on the server side, only iterate on client side and perform last step of hashing on server.
  • Protecting against password leaks if server is compromised by deriving a public key pair from the password and never let the server see password or secret key.

As others have said this is a standard approach.

However for a personal site I wouldn't necessarily follow it... I would use federated login from Facebook, Google or similar as that way I don't have to handle account life-cycle issues, and can use Google 2 factor Auth etc.

It saves having quite a few forms and fields in your database which means less to go wrong.

Of course you would still need to authorise those users you wish to be able to access either through a function of the authentication provider such as a Facebook group, some sort of whitelisting of allowed users, or an approval work flow off your account. Sometimes this is done by inviting users: giving them a URL containing a unique secure code and the your system linking that to an Auth provider on first login. Alternatively users authneticate and request access. This places them in a "pending" state. You then provide an interface where you can login and approve them.

  • 1
    Bit I don't want everyone to join: I want to give permission only to certain users (e.g. my friends). – Emiliano Aug 5 '14 at 19:34
  • Yes, you need a list of emails that are allowed still. You then check that against the federated Id. – Andy Boura Aug 5 '14 at 19:37
  • Ah, so I can implement a white list, you mean? That is interesting, I'll look into this approach as well. – Emiliano Aug 5 '14 at 19:58
  • That's right. You could potentially even use your Facebook friends list or a group for Auth but I'm not familiar with details of how you would do it. – Andy Boura Aug 5 '14 at 19:59
  • Added more authorisation info to answer. – Andy Boura Aug 6 '14 at 19:29

HTTPS makes the authentication request unsniffable in transit. However, to make it "safe", there are other things that you also need to get right. For example:

  • The entire login page and all of its dependencies should also have been served over HTTPS, even though no password is being transmitted then. Serving any part of it (such as JavaScript, CSS, or image resources) over unencrypted HTTP would let an attacker modify the appearance or behaviour of the login page through a man-in-the-middle attack.

    Browsers will treat mixed HTTP/HTTPS content with varying degrees of suspicion. Some will merely suppress the 🔐 "lock" icon in the UI. More paranoid browsers will refuse to load the unencrypted dependent resources altogether. Either way, you should serve the entire login page over HTTPS.

  • Do not submit the password in the query string of an HTTP GET. Webservers are typically configured to log the URLs of requests, which would include the query string portion of the URL. Put the password in a POST body instead. (You could also use RFC 2617 HTTP authentication, but logout support is spotty.)

  • Ah yes, I always remember GET is a bad idea because it is visible on the client system and may end up in client history, but forget that servers may log the parameters too. – AJ Henderson Aug 5 '14 at 16:41

Wikipedia that has the full page of historical HTTPS security issues.

HTTPS security bugs have happened before (why the two older versions are broken? And what is 'goto fail'? What is 'https freak'?).

I do not suggest to ditch HTTPS, but placing something additional underneath will make no harm in most cases. If you already can send unencrypted password through that channel, you can probably send whatever you want.


The use of HTTPS does not prevent attempts to brute force the password. So if you are rolling your own user account management, then you might want to consider features such as minimum password complexity and account lockout / maximum number of retries that would mitigate against such attempts.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.