2

Let me start off by saying that I read other StackExchange questions related to this and they weren't really able to answer my question. I have a feeling this may be an unsolvable problem, but I'm wondering if maybe there's a happy medium that will satisfy my requirements.

I have an Android application. However, it's not login-based in the traditional sense that users don't sign up with an email or anything. We just automatically create an account for them with some randomly generated UUID as their "login" to the service. To get this UUID, the Android application sends a request to a webservice indicating that they are a new user who just installed the application. The webservice then returns a UUID that will be used for any further accesses to the application. The point of this is to make it so that user specific information can still be stored in the database, but users don't have to go through the hassle of creating an account and logging in every time.

Obviously, requests to the webservice for other actions are all restricted by having a valid UUID. However, the webservice for creating the account has no restrictions, meaning an attacker could spam GET requests to it from any device to create any number of users they want and flood the database/server.

My question is, how can this be avoided? I understand the concept of a secret embedded in the Android application to access the webservice, but it seems like any client-generated secret could be easily obtained by an attacker by decompiling the APK. Another idea was to restrict access by MAC address, meaning only MAC addresses with the app installed could reach the user creation web service URL. But because of MAC-spoofing, that also seems like a bad idea.

Is there a good way to have a client-generated secret that isn't easy to obtain by examining source code? I know this is a very difficult question but if anyone has some insight that would be great.

  • 1
    "Another idea was to restrict access by MAC address." This only works for devices that are on the same subnet as your server, because MAC addresses are layer 2 and IP routing is layer 3. – Mark E. Haase Dec 4 '14 at 18:10
0

However, the webservice for creating the account has no restrictions, meaning an attacker could spam GET requests to it from any device to create any number of users they want and flood the database/server.

My question is, how can this be avoided?

You can use a mix of CAPTCHA and IP restrictions to avoid such type of attack.

IP restrictions:

An unique IP can create a maximum of X accounts in an Y amount of time (Y seconds, or minutes, or hours, or days, etc., just you can balance the right amount).

CAPTCHA:

CAPTCHAs are commonly used in an effort to prevent automated account sign up, then you can require a CAPTCHA challenge-response to create an account.

Mix CAPTCHA and IP restrictions and you are done.

Is there a good way to have a client-generated secret that isn't easy to obtain by examining source code?

I didn't understand your question.

1) If you want to protect your server just against flood, the answer is above.

2) If you want to protect the user data, so nobody can send requests to your server to get the informations of user with UUID X, you can create a random token specific to an UUID when creating the account and can store it in a encrypted database on Android.

EDIT:

See the new "No CAPTCHA reCAPTCHA”.

http://googleonlinesecurity.blogspot.com.br/2014/12/are-you-robot-introducing-no-captcha.html

Painless for your users, effective to you.

  • 1
    Thanks for the response, I appreciate it. What's the difference between using the UUID as the token as opposed to a separate random token? Since the UUID is already random isn't that just adding another element of randomness? – Daniel Hipke Dec 4 '14 at 4:27
  • @DanielHipke I said to you use a random token because I don't know how you create the UUIDs. If it is guessable, an attacker could enumerate your users and request informations about them to your server. The token would be completely random and very long, to prevent from brute force (the UUID would be the login and the token would be a password). – Lucas NN Dec 4 '14 at 6:02
  • 1
    The UUIDs are randomly generated as well. I guess it doesn't make sense to me to have a randomly generated UUID and an additional randomly generated password. Since both are just random, it seems like the only thing you are adding by using a "password" token is more random bytes. Wouldn't it be better to just make the UUID longer? The idea is that people using the android app aren't aware of their UUID. Thanks again for the responses! – Daniel Hipke Dec 4 '14 at 6:38
  • @DanielHipke If your UUID is not guessable and is long, then you are not in trouble and don't need an additional random token. =) – Lucas NN Dec 4 '14 at 6:52
  • Another question. If I want to encrypt the UUID being used as the sole user identifier in the database, what should I do? It seems to me like you can't encrypt a unique identifier well without a password. Because (with a good encryption) you shouldn't be able to generate the same hash on every encryption of the same UUID, authentication with encryption seems costly. Assuming you are storing the salt in the encryption, wouldn't you need to iterate through all possible encrypted UUIDs in the database until you get one that matches to know if the user requesting web service access is valid? – Daniel Hipke Dec 5 '14 at 8:12
-1

However, it's not login-based in the traditional sense that users don't sign up with an email or anything. We just automatically create an account for them with some randomly generated UUID as their "login" to the service.

If you are just allowing ANY user to create an account with your application, without providing any personal information, it is very likely that your application is going to be spammed with a large number of requests to create new users.

The point of this is to make it so that user specific information can still be stored in the database, but users don't have to go through the hassle of creating an account and logging in every time.

Actually, this a bit confusing. What exactly is this user-specific information? Where did it come from if the user never signed up with your app? If it is something unique such as an email id or phone number mapped with the user assigned UUID, then this unique information can be used for a simple Challenge-Response authentication, which can essentially stop the scam. The fact that your application is allowing users to sign-up, without providing any personal information (which is unique and can be used to authenticate that user in the future), makes your application vulnerable to such spamming attack.

  • By "user-specific information" I mean data that is created by the user in the app that gets stored in the database. And I'm aware that our implementation allows for new user requests to be spammed, but even if you had to provide information (like an email address and password) couldn't you still spam the webservice to create new users with fake emails and passwords? – Daniel Hipke Dec 4 '14 at 2:11
  • @DanielHipke: Yes, you're right. But it will make the task of an attacker much more difficult (since the attacker will now need fake email ids). – Rahil Arora Dec 4 '14 at 2:57
  • @Downvoter: Any explanation for the downvote? – Rahil Arora Dec 4 '14 at 4:25

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.