1

I am trying to come up with a way to implement token-based authentication for a REST API without the need for SSL. The goal here is to avoid sending any sensitive information across the wire.

I was thinking of the following approach:

Step 1 - Client asks for request token from server and supplies a username.

Step 2 - Server returns user password salt & request timestamp.

Step 3 - Client then calculates password hash based on salt + actual password (captured via input)

Step 4 - Client then generates token by hashing password hash + request timestamp.

Step 5 - Client sends token & username & request timestamp to server

Step 6 - Server verifies authentication by re-generating same token with details provided.

From what I can tell nothing that isn't public already is going over the wire so packet sniffers would be out of luck. The token is hashed using the original password (essentially the secret key) so MitM are covered. Finally, the original timestamp from the initial request is sent back (and is part of the hash) therefore Replay attacks should be out of the question.

I have only started looking at security therefore pretty much a novice at this stuff so any help/advice would be appreciated!

Update

I should have been more clear with regards to the SSL.... it's not that I am trying my best to avoid using SSL, it's more catering for the scenario where it isn't an option. Also, please target your answers more to the reasons why this approach wouldn't work & if it could be tweaked to work rather than "use SSL".

23
  • 1
    Discloses user's user name.
    – chao-mu
    Commented Jul 4, 2012 at 22:51
  • @chao-mu Username is already publicly available, consider a twitter type system.
    – James
    Commented Jul 4, 2012 at 22:54
  • 1
    But not necessarily publicly associated with the origin of the request. This would allow an attacker to focus their attack.
    – chao-mu
    Commented Jul 4, 2012 at 23:00
  • 1
    As is the usual: Don't try and roll your own xx just to bypass SSL. Why can't you use SSL?
    – Steve
    Commented Jul 4, 2012 at 23:44
  • 1
    @James "Username is already publicly available, consider a twitter type system." knowing the list of registered user names is not the same thing as knowing the user name used in every requests
    – curiousguy
    Commented Jul 5, 2012 at 0:00

4 Answers 4

10

I am trying to come up with a way to implement token-based authentication for a REST API without the need for SSL.

Don't!

Use SSL (well, TLS actually).

nothing that isn't public already is going over the wire

This is obviously not exact:

  • the user name is captured; TLS would hide user name (I am not saying it is a serious still, but it is an information which is disclosed);
  • a hash based on available information is captured and passwords can now be tried (dictionary attack).

I have only started looking at security therefore pretty much a novice at this stuff so any help/advice would be appreciated!

Use the proper tools. Don't try make your own protocols. If you try to come up with your own security protocols, they will almost always be flawed.

There are many issues with your protocol:

  • discloses user name (might not be huge issue, but still)
  • discloses password hash: allows off-line attack on password
  • the server needs to know all passwords in clear-text (either by storing them in clear-text, or storing them encrypted with symmetric encryption, and storing the encryption key) (well not the user password, but the real user secret authenticator)
  • and the worst part: absolutely no protection against an active attacker

Replying to your update:

I should have been more clear with regards to the SSL.... it's not that I am trying my best to avoid using SSL, it's more catering for the scenario where it isn't an option.

Why isn't it an option in this scenario?

Also, please target your answers more to the reasons why this approach wouldn't work & if it could be tweaked to work rather than "use SSL".

TLS gives you transport level "security": secrecy and integrity (actually, secrecy is limited, as the size of message is leaked; the secrecy of fixed-size keys is protected).

It can be "tweaked" to work without actually using TLS, if you reimplement most of TLS to get transport security without TLS. The implementation cost would be great, and even if you can get all the details right, your implementation might not perform as well as a carefully optimised TLS implementation.

The important question is why you would not want to use TLS.

8
  • Ok I can see where this sort of approach is vurnerable. Would you say using Basic authentication with SSL is pretty secure?
    – James
    Commented Jul 5, 2012 at 8:09
  • @James If the TLS certificate of the server is properly checked, then yes, I would say it's secure. Be careful about your root certificates store: only keep necessary root certificates. One rogue CA is enough to compromise TLS server authentication.
    – curiousguy
    Commented Jul 5, 2012 at 13:36
  • From what I have been reading though TLS isn't always enough you should still provide some form of protection on the actual data being transmitted e.g. blogs.msdn.com/b/vbertocci/archive/2005/04/25/…
    – James
    Commented Jul 5, 2012 at 13:47
  • Like I said it's not like I want to not use TLS, I am not the guy who makes the decisions therefore if I come up against "we can't afford a TLS" then I was hoping there could be another alternative. From the answers I have been given (not particular to my protocol suggestion) it appears the answer is no. Are you able to generate your own TLS certificate if it's used purely for encryption & not for authentication?
    – James
    Commented Jul 5, 2012 at 18:12
  • @James "if I come up against "we can't afford a TLS"" then answer: how do you know? have you tried? If TLS is too costly, maybe it's just a bad configuration. F.ex. there is no point wasting cycles with a 4000 bits RSA key, as this won't be the weakest point of the whole system anyway. If you have questions about the performance of TLS, there are experts on this forum.
    – curiousguy
    Commented Jul 5, 2012 at 19:17
6

You disclose enough information to allow offline brute-forcing of the password.

Let's review. The eavesdropper knows the timestamp, salt, and result of hash(hash(password + salt) + timestamp). The attacker can run hash(hash(guess + salt) + timestamp) repeatedly with different values of "guess" until the result equals the observed token. The password is then known.

8
  • 1
    Yeah I see where your coming from now, if the username wasn't part of the request would it make it any less vurnerable?
    – James
    Commented Jul 5, 2012 at 8:19
  • 1
    The password could still be brute forced, since I am describing an offline attack.
    – chao-mu
    Commented Jul 5, 2012 at 13:38
  • The example I took this from is stackoverflow.com/questions/9386930/…. I was thinking I could possibly get away without using the who API key end of things (as I am not publically opening the API up to developers). Is it possible to implement a token-based system which is secure without having to implement something like oAuth....that article seems to suggest it's doable?
    – James
    Commented Jul 5, 2012 at 13:43
  • 1
    I think further discussion may be better had in its own thread. "Doable" can mean a lot of things. You certainly will not be saving time/effort/tears trying to write it yourself.
    – chao-mu
    Commented Jul 5, 2012 at 14:19
  • 1
    @James removing the username would be like taking a cup full of water out of the ocean. Even if somehow the username could be removed, the attacker probably can figure it out through other means (as you said it was publicly available). Your question has been fully answered with plenty of examples: there are vulnerabilities in your authentication mechanism.
    – chao-mu
    Commented Jul 5, 2012 at 17:51
6

This is horribly wrong. As curious guy said, never never never try to make your own authentication protocols. What is more disturbing is that you confidently say it avoids replay attacks, when it doesn't at all.

If someone with a sniffer captures Step 5, he will always manage to login, because the client is sending back the timestamp and the server trusts it. So you can reuse that timestamp forever, until the password is changed. Even if you add a time window, the attacker only needs to automate it to login as soon as the client sends his response.

8
  • 1
    I don't recall ever confidently saying it avoids replay attacks, I said should be out of the question based on my understanding. I thought by hashing the timestamp as part of the token and sending it back across the server could then check if the request token for that user has already been A) authorised or B) expired.
    – James
    Commented Jul 5, 2012 at 8:00
  • @James "check if the request token for that user has already been A) authorised or B) expired." So, you need to explicitly mention the expiration check in the protocol, and you need to describe precisely the way the check is run. In a security protocol, all the details matter.
    – curiousguy
    Commented Jul 5, 2012 at 16:41
  • @curiousguy I will update the my question to accomodate that, I should have explictly stated that's what the purpose of the timestamp.
    – James
    Commented Jul 5, 2012 at 17:42
  • Checking if request token was authorized doesn't help, because attacker could after observing step 2 disrupt communication with the client (e.g. by some kind of network attack slowing down client's network) and issue his own response with the timestamp first. If you allow only one response with this timestamp, you then allow very easy DOS attack on the protocol - I can prevent any client from logging in as long as I can send response faster than they do. If you allow many responses with the same timestamp, I can bruteforce it.
    – StasM
    Commented Jul 6, 2012 at 4:19
  • @StasM "you then allow very easy DOS attack on the protocol - I can prevent any client from logging in as long as I can send response faster than they do." which protocol does not have this property?
    – curiousguy
    Commented Jul 7, 2012 at 1:45
2

There are a couple of big problems here.

If you're talking about a browser as the client, then you've got a major vulnerability straight away. Unless you're implementing the code as a greasemonkey script (i.e. already at the client) then the code to implement step 3 has to be sent over the unencrypted channel (presenting an opportunity for it to be intercepted and modified).

Leaving this aside, your proposal will authenticate the username - but how do you then maintain a session / authenticate further requests from the client?

Even without knowing the username and password, nor changing the data stream, an eavesdropper could assume the indentity (depending on how session management is implemented) by sniffing and replaying the token provided by the client.

Yes, it's a bit better than sending a password in clear text - but only just. And yes, there is a benefit in preventing the diclosure of a password even where there is no requirement to add strong security to the actual transactions being processed (but your approach can be subverted by MITM to reveal the actual password).

5
  • If the salt is intercepted & modified at step 2, surely this would simply mean that when the token comes back to the server the hash values won't match and the server would reject (as the salt has changed). Also, I don't see how the original password could be revealed (unless you are referring to brute-force attack). If the salt is high-entropy e.g. 16+ bytes, surely this would practically nullify the chances of it being cracked in any reasonable amount of time?
    – James
    Commented Jul 5, 2012 at 15:13
  • @James "If the salt is intercepted & modified at step 2," who said the salt would be modified? "If the salt is high-entropy e.g. 16+ bytes, surely this would practically nullify the chances of it being cracked in any reasonable amount of time?" entropy? what are you talking about? The salt is sent in clear. It is constant for a given user, and known by the attacker (who can listen to packets on the wire, by hypothesis). The entropy of the salt is zero.
    – curiousguy
    Commented Jul 5, 2012 at 17:33
  • @curiousguy yeah that was a misunderstanding on my part.
    – James
    Commented Jul 5, 2012 at 18:04
  • "If you're talking about a browser as the client" The question was not explicit about the context (generic client/browser vs. specialized client), but James latter explained he was talking about a mobile app, so this particular concern does not apply in his case. But still, it is an important remark.
    – curiousguy
    Commented Jul 6, 2012 at 18:44
  • @James: if the client is a browser, then the code used to generate the hash is sent as cleartext javascript and can hence be modified
    – symcbean
    Commented Jul 10, 2012 at 9:51

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .