views:

890

answers:

9

For a webapplication, when HTTPS is not available as a security measure, is it possible to still make the login somewhat secure? E.g.:

  • Tokenize logins, to make repeat attacks difficult?
  • Somehow encrypt the sent password from a HTML password field?

In particular I'm using CakePHP and an AJAX POST call to trigger authentication (includes provided username and password).

Update on the problem:

  • HTTPS is not available. Period. If you don't like the the situation, consider it a theoretical question.
  • There are no explicit requirements, you have whatever HTTP, PHP and a browser (cookies, JavaScript etc.) offers in real life (no magic RSA binaries, PGP plugins).
  • Question is, what is the best, you can make out of this situation, that is better than sending the passwords plaintext. Knowing the drawbacks of each such solutions is a plus.
+2  A: 

You can encrypt the password using Javascript and decrypt it on the server.

I would recommend generating an RSA keypair on the server, send the public key along with a timed salt to the browser, then encrypting the password, combined with the salt, using the public key in Javascript.

You can find an RSA implementation in Javascript here

You should include both the IP address and the entire X-FORWARDED-FOR hedaer in the authentication cookies to prevent cookie theft behind proxies.

If you're dealing with sensitive data, you could generate a random AES key in Javascript, then send it to the server along with the password encrypted with RSA.
You could then make the entire application use encrypted AJAX requests from a single page and not use an auth cookie at all.

Note that it is not possible to protect against an active man-in-the-middle attack without SSL. An active attacker can completely replace your site with his own proxy, and there isn't any way to defend against that. (Since there cannot be any known good code)

SLaks
This is a valid use of RSA, but its a moot point. Its not going to stop anyone from getting hacked.
Rook
Is RSA possible in JavaScript today?. A few years ago I was looking at them, and they did not scale to current key lengths.
sibidiba
X-FORWARDED-FOR is not set by all proxies. Also it is trivial for an attacker to spoof X-FORWARDED-FOR.
Rook
The author knows what he is doing regarding cryptography and security, but I don't know if he considers the implementation a secure alternative to SSL. In particular the PRNG looks potentially weak which would undermine the entire thing anyway. There are also attacks on PKCS #1 that this may be vulnerable to. http://www.iacr.org/archive/eurocrypt2000/1807/18070374-new.pdf
mctylr
Actually, I don't see how this approach prevents a man-in-the-middle attack.
mctylr
@Michael: AFAIK, if you use the _entire_ XFF string plus the physical IP address, you aren't vulnerable to spoofing. (Except for proxies that don't set it)
SLaks
@mctylr#2: It doesn't. Read my last paragraph
SLaks
Okay, I did not notice your additional two paragraphs that you added after your initial answer. No problem, glad we can agree.
mctylr
+16  A: 

The short answer is that HTTPS does a lot more than just encrypting passwords. Another important role is that it should prevent you from giving your password to a malicious server in a MITM attack. Using JavaScript to obscure your password is still violation of the OWASP A3 Broken Authentication and Session Management.

1) Tokenize logins: This doesn't matter, if an attacker is sniffing the traffic they'll have the plain text username/password and then they can just login normally.

2) Somehow encrypt the sent password: After the person has logged in an attacker can sniff the traffic to get the valid session id (cookie) and then just use this instead of logging in. If the entire session was protected with SSL then this is not a problem.

There are other more compelx attacks that affect both this system and our current SSL infrastructure. The SSLStrip attack goes into greater detail. I highly recommend watching Moxie Marlinspike's Blackhat 2009 talk.

Rook
I'm (somewhat) aware of what S offers in HTTPS. But HTTPS is *not* available in this case. My question is still open, what is the best, what is worth doing, when it is not available?
sibidiba
@sibidiba https should always be available, even if it is a free self-signed certificate. If it is not then another encrypted tunnel such as a VPN can be used.
Rook
HTTPS is ***not*** available. Existing problems most of the time can not be solved by requiring the situation to change into one where the problem does not exit. Assume you are stranded on the South Pole after a plane crash./Survivor: How do we get out of this? There is no mobile network coverage to call help./You: We must call help on phone!/Survivor: There is no network coverage on this continent./You: Network coverage should always be available.
sibidiba
He's probably on shared hosting with not shared SSL certificates.
rFactor
The Rook has listed many of the myriad caveats about the ways you're gonna shoot yourself (mitm is particularly bad here). The only other suggestion I have is to look at Digest Authentication, which is not particularly swell. It's still susceptible to MITM because without an SSL login page, I don't even know if the HTML for the login prompt came from you, so I DA could get turned off on me. Basically you're making a joke of your password system. I'm not saying that to be mean or in-your-face. Figure out how to break the 'no-SSL' problem, or pray nobody gets interested in your site.
Jason
@sibidiba: The point is that without SSL, you *can't* make it secure. Yes, the scheme you linked to is "better than plaintext passwords." But it's still not even "somewhat secure." Sometimes there just isn't a good solution to a problem, other than changing the scenario. If you want security, your hosting choice (or whatever the limitation is) is wrong.
Andrew Coleson
@Andrew: so because WEP encryption is easy to crack, you use *no encryption at all* when only WEP is available? Crackable does not mean that the attacker you aim for is also on the level.
sibidiba
@sibidiba: You must've missed the part where I said "Yes, it's better." That doesn't mean you would call WEP "secure", because it isn't. Yes, it's a question of semantics, but it's an important distinction whether you call something "secure."
Andrew Coleson
@sibidiba [Network coverage is always availble](http://en.wikipedia.org/wiki/Satellite_phone)! Every webserver supports the equivalent of sattelite phones, by default.
alexanderpas
+9  A: 

As you suggested, you may be able to generate a unique token each time the page is created. That same token would need to be sent back with the form data and could not be reused. You could also keep the password safe by using JavaScript to hash it, if you can rely on it being enabled by your users.

This scheme is still not secure, however. An attacker could still see everything going across the wire. They could intercept the token and send a response back to you before the user does. Or they could just wait for someone to login, steal that person's credentials (as they are sent over the wire), and just make their own login request later on.

Bottom Line - you need to use HTTPS to guarantee the site is secure.

Justin Ethier
+2  A: 

You can use HTTP Digest authentication, which is supported by most browsers and does not send the password in clear over the wire.

The downside is the ugly log in box displayed by broswer. If you preffer to stick with forms, then you can implement exactly the same protocol as HTTP Digest in your forms authnetication: send hidden fields containing the realm and the challenge, and have the client add in JavaScript the nonce and compute the digest. This way you'll use a well known and proven exhange protocol, rather than roll your own.

HTTP Digest requires only hash operations.

Remus Rusanu
Is logging out possible by now? How can I detect from the server side that the login was a success?
sibidiba
You are still in control of the authentication process, it happens on the server php scripts. You authenticate the response form against a user database where you have the user name and the HA1 part of the http digest ie. md5(user:realm:password). From the response you reconstruct the Digest hash, starting from the HA1 stored in the database and compare it with the response in the form submit, if they match it means the user had the correct password.
Remus Rusanu
The big advantage over other schemes is that it allows for a unified authentication model for browser/user sessions (using forms and cookies, but not transmitting the password over the wire) *and* REST services, using HTTP Digest.
Remus Rusanu
Logging out is handled the usual way, by resetting the auth cookie. It is true though that if the user hits in the browser a part that challenges him to do HTTP digest (eg. enters an REST URL from the site) and if the user enters the correct password in the browser log in dialog, is much harder to log out: the user has to manually clear the password from the browser setting. But that should not happen normally, as the UI part of the site is usually separated from the REST part.
Remus Rusanu
+1  A: 

What about HTTP Digest Authentication? It provides security by MD5-hashing username, password and a nonce (among other things) before sending it to the server. MD5 isn't really secure, but it's a good way for simple security with HTTP.

Of course this doesn't prevent hackers from changing the message... but it secures your password.

AndiDog
+1  A: 

The best solution I have seen for somewhat secure HTTP connections is to use a Javascript implementation of md5sum (or some other hash) to avoid transmitting the password in plaintext. You can create a form onsubmit handler in Javascript that replaces the password field with a hash of the original value. This adds a modest amount of security to an unsecure connection, but relies on Javascript running in the browser to work properly.

brandon k
This doesn't stop anything, the attacker will just hijack the session after it has been authenticated.
Rook
Whatever Michael said. If you do go with md5, at least have server send unique challenge, client should send md5(challenge+pass). Sending md5(password) for most users is same as pass in clear. More than replay, the bigger concern would be passive attacker can crack most of your users password.Also if you are over http and you have active attacker, apart form replay and hijacking, it has been demonstrated that attacker can inject script to modify the login form so that they get a copy of entered username, password.use https unless you are supporting some weird mobile device.
mar
A: 

You don't need SSL.

You don't need asymmetric encryption.

You don't need symeetric encryption.

See http://groups.google.co.uk/group/comp.lang.php/browse_frm/thread/c5960aa0afac2621?hl=en&tvc=1&q=Proposal+for+Lite+Encryption+for+Login+Form+without+SSL

For a discussion of a secure login system.

Note that without SSL you still run the risk of session hijacking.

C.

symcbean
This is still vulnerable to MITM. You do need SSL.
SLaks
@SLaks: HTTPS is not available.
sibidiba
@sibidiba: Why not?
SLaks
@SLaks: There is none. See question update. There is no HTTPS available. The question is about that particular scenario.
sibidiba
@sibidiba: I realize that. I'm asking why.
SLaks
-1 you do need ssl and don't let anyone tell you otherwise.
Rook
@SLaks: shared hosting made the idea
sibidiba
The question asked was wether you can make the login secure without using SSL. This is **not** vulnerable to MITM. The password is **NOT** recoverable. Everything after is not secure - which I pointed out.
symcbean
@symcbean, you don't need the password if the token is just as good. This is vulnerable to MITM attacks. @The Rook, you don't really need SSL, but you do need asymmetric encryption and certificate validation or something equivalent.
Marcus Adams
@Marcus Adam: Any encyption (including asymmetric) applied without key authentication (e.g. signing, preshared secrets) is just as vulnerable to MITM attacks.
symcbean
@Symcbean, I agree that you need what you call key authentication, only I called it "certificate validation". However, you're not "just as vulnerable", but definitely vulnerable.
Marcus Adams
A: 

This is not practically a easy thing to do.

But you could play with other crypto system that is designed for unencrypted connection, maybe sign all your data with pgp or something like that.

But you still may have a problem with "man in the middle" attacks, if you only encrypt the login data. (someone could just resend that data and also get access).

So I can't see this becoming simpler (or safer) that https.

Johan
+5  A: 

Since you cannot do SSL at the web server, and you are not a security expert, look for an existing secure authentication service that you can utilize, and let them handle both the SSL and the complexities of handling credentials for you.

In particular, I would suggest that you use a free third-party authentication service, such as OpenID. They have libraries for PHP including one for CakePHP.

mctylr
My thinking exactly. If you can't have SSL on your server, let a third party do the SSL for you.
stevenf