10

I'm a software developer with an interest in and basic level of knowledge about security. I've come across an authentication system that "smells bad" to me however I lack the expertise to know what if anything is wrong.

The software system involves web services for downloading and uploading data from/to a database over the public internet. All communication occurs over HTTPS and a random 32 bit integer identifies the user. Requests from unknown user ids are dropped.

Something about this seems weak but I'm not sure how weak and whether it's worth advocating change. I suppose this is equivalent to a 5 character alpha (upper/lower case) numeric password with no associated username (log62(4 billion) ~ 5) and if I look at it in those terms it seems completely anemic.

My gut instinct about what to do for authentication would have been to expose a web service operation for "logging in" that takes a username/password and passes back an authentication token (for example a cryptographic hash based on the credentials and the current time) which is then good for a certain amount of time or until the user requests a log out.

I believe my approach is more secure mainly because the credential space is dramatically larger and because the authentication token changes over time, whereas in the current system the credential space is small and the authentication token never changes. But I have no reference point... what kind of adversary would the current system fail against? What kind of adversary would my idea fail against?

The argument in support of the current system is that we are a small player with small customers in a large world so we're not expecting to be attacked, and if we are attacked we do have some level of security. My thought is that security threats are becoming more numerous and more sophisticated pretty quickly, and we do happen to be in an industry where security is a concern. I don't want to give specifics here just because I may be pointing out the existence of a poorly secured live system, but perhaps someone knowledgeable could speak to current trends in security threats?

I would appreciate any input on this topic, and if for some reason my question is inadequate please let me know so I can update it accordingly rather than marking it to be closed!

4
  • As well as the brute-force argument, you would have to make sure that your IDs don't leak out by other means. For example if a record is returned to the client as "edited by user 18457629" or similar, that's their account gone! You might also argue that username-and-password is more convenient for the user than remembering an arbitrary 32-bit number. (And a federated login system like OpenID as this site uses it might be more convenient still, depending on who your users are.)
    – bobince
    Dec 18, 2013 at 23:48
  • You're right about the leaking issue... after I realized how things were authenticated I started seeing that number pop up in the darndest places! The system is automatic though so people don't actually sign in. But that kind of talk opens a whole other can of worms, regarding storing credentials securely (or not). I'm thinking if we implement real authentication we can keep the credentials in memory but require the user to re-enter them if their machine reboots. But then if hibernate is turned on I guess credentials could be persisted anyway... time for more research ;)
    – Paul
    Dec 19, 2013 at 14:37
  • **Or if paging is turned on, which is always the case
    – Paul
    Dec 19, 2013 at 14:38
  • That's one reason I mentioned federation (OpenID or SAML): it may be more complicated initially, but it takes the problem of authentication and credential storage out of your hands; Google (or whoever your clients use) can work that bit out.
    – bobince
    Dec 19, 2013 at 17:28

2 Answers 2

10

I assume that the user ID are attributed randomly and uniformly among the 232 possible 32-bit values. In that case, the best an attacker can do is to try potential user IDs (32-bit values) in any order until a proper one is found. If there are N valid user ID, then the average number of tries that the attacker will need to perform will be close 232/(N+1): if there are one thousand of users, then the attacker will need to connect about 4 million times to your server before being granted access. Once the attacker gains access, he can reuse the ID at will.

Your only defence in that case is to try to detect such brute forcing, e.g. by banning IP addresses from which come too many failed attempts. This has limitations; in particular, when many people are behind some kind of Web proxy or NAT, they may, from your point of view, share the same IP address, so you risk disabling a lost of users with a lockout strategy. Conversely, attackers can rent botnets in order to perform their one-time brute force from a lot of distinct IP addresses.

One way to look at it is indeed to consider the user ID to be some kind of password; in that view, the attacker can attack the passwords for all users simultaneously. The security level is thereby lowered when there are more users, as can be seen in the mathematical expression above: more users means more targets for the attacker, without increasing the search cost.

A login+password strategy is what most people do. This is much better: when trying to brute force a password, the attacker must select a specific user name, and will be able to break only that specific password. The "user name" is a non-secret piece of information that is specific to each user. With user names, the attacker's task is no longer a thousand times easier when there are a thousand of users. As for a "session token", well, there are several methods which are more or less equivalent (token in the URL, token as a POST parameter, token as a HTTP header -- also known as a "cookie" --, and so on); SSL itself has its own notion of session and you could reuse that.

Summary: the "secret user ID" with no user name strategy can be secure, but only if the space of possible user ID is large enough to defeat brute force, even if there are many valid user ID. This requires large user ID which must be selected randomly and uniformly. 128 bits would be enough. 64 bits would make me quite nervous. 32 bits are way too small.

5
  • 1
    Thank you for your analysis, this helps my understanding of the issue... I hadn't considered that increasing user count actually weakens the security.
    – Paul
    Dec 18, 2013 at 19:50
  • Do you know anything about who might mount the type of botnet attack you propose? For example, could small time criminals pull that off or are we talking about organized crime / larger companies / governments?
    – Paul
    Dec 18, 2013 at 19:50
  • Botnets are for sale and can be afforded by petty criminals. Actually even a bored student at some university could use the machines at his disposal to run the attack (students are the worst: they have free time, access to lots of machines, low inhibitions, and are eager to do irrational things just for the sake of it, even if it cannot benefit them in any way). Dec 18, 2013 at 19:56
  • Wow. I think perhaps the barrier to entry for attacking this system is lower than its designers expected. I'm going to mark this as the answer, thanks very much for your help.
    – Paul
    Dec 18, 2013 at 19:59
  • I would upvote but my reputation isn't large enough :O
    – Paul
    Dec 18, 2013 at 20:00
3

The easy argument is that 32 bits is well within brute forcing limits, depending on how many attacks per second is possible it will probably take something in the range a week to a year to search the entire space. Divide that time by the number of users and you have an approximate time frame for the attacker to find one account.

I don't know the details of the implementation, a per IP login request throttling makes an attack harder, but probably not enough harder. Is it possible to deduce the ID space from just looking at the public code? Right now your strongest defence may be that not a lot of people know that all user IDs are integers. It is not something I'd rely on, but a dictionary brute force attack without the integer knowledge would be a lot harder.

Also, whoever wrote this code in the first place obviously isn't very security minded, it seems likely that there may be other issues. Cross site request forgery, SQL injections, or perhaps even some "fast" C code with old-school buffer underrun.

3
  • You are correct, security was not the first priority when this code was written. I've walked in on this project now, a few years after inception, and hope to clean things up as I touch things :)
    – Paul
    Dec 18, 2013 at 20:02
  • You raise a good point about the timeframe, at 127 requests per second it takes one year to run through 4 billion possible values. Dividing by the number of users brings that down to a scary time interval!
    – Paul
    Dec 18, 2013 at 20:04
  • My reputation is now large enough to upvote... upvotes for everyone!
    – Paul
    Dec 18, 2013 at 20:04

You must log in to answer this question.

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