9

Let's say I have an iOS/Android app which rely on a custom REST API for things such as account management (register, login, password reset, get/set user-related data).

There is no good way to guarantee my API is only called from my mobile application. Oauth2 and the like with 'secret' in the client code - can be easily reverse-engineered.

Let's say I have an API call like this:

https://www.myapi.com/register_user?username=UUU&password=PPP&email=EEE

(of course, not exactly like that but you get the idea)

This create a new user and from then all API calls will either include a session-token or something that ties the API call to a specific app user with an account.

This first registration call is the only one that is not protected by anything and what I'm worried about is that a malicious person calls it 1,000,000 times from a PC script to create lots of fake users, especially with real email addresses. People with these addresses won't be able to use the app.

So How to protect that very first API call to prevent mass misuse? I'm thinking of including a server-validated mobile-friendly CAPTCHA in the user registration form.

Again, all subsequent API calls are protected with session-token and API-call-count monitored per user (suspicious ones are blocked).

Does that make sense? Am I over-complicating things? Many Thanks

PS: It seems other interesting alternatives include using email-validation or a solid third-party identity provider like Google and the like - None of these 3 options is perfect. Anyway, interested in the discussion around this issue.

MikaelW
  • 1,145
  • 4
  • 11
  • 29
  • So this is less about securing access to the API itself, but rather about securing the sign-up process? If you are worried about someone registering with existing email-addresses that are not their’s – well then implement an email verification system, where a confirmation email is sent to the email address first. – CBroe Aug 10 '14 at 16:29
  • Well, it's about designing the API in such a way that even if used from an inherently unsafe client like a mobile, it is still fine. Basically even if the API were to be made completely public, nobody could do much wrong with it. So here the question focuses on 'protecting' that first call but it's about 'solving' a more general problem. – MikaelW Aug 11 '14 at 11:15
  • And OAuth2 doesn’t solve this “more general problem” in your opinion? – CBroe Aug 11 '14 at 11:54
  • From everything I read, not when accessed from a binary on an unsafe device like a mobile phone where the app can easily be decompiled/reverse-engineered in seconds and the Oauth2 'secret' hidden in the code stolen. Anybody can then call my API pretending to be my app. http://stackoverflow.com/questions/7623335/how-do-i-protect-oauth-keys-from-a-user-decompiling-my-project – MikaelW Aug 11 '14 at 12:02
  • What was your final solution for this issue? – Jelle Jan 22 '15 at 16:08
  • http://security.stackexchange.com/questions/65116/rest-api-does-securing-the-first-call-with-a-captcha-make-sense?noredirect=1#comment119985_65116 Basically email verification or captcha depending on the kind of app. – MikaelW Jan 26 '15 at 13:56
  • Email verification is not safe because hackers can use tons of emails to register and automatically check emails, only captcha can stop the automation process of registration. – soulmachine Nov 19 '15 at 22:39

1 Answers1

3

I suggest CAPTCHA to be a second level of protection to be turned on when you're seeing registration abuse. There are a couple of different angles here:

1. Does your app need this protection at all?

Unless you're assigning expensive resources right away when the account is requested, all that's happening is that a bunch of database records are being created. If you are allocating resources immediately, then you need to change the onboarding flow so that users are given those only after they legitimately verify their emails and login to the app. You can separately institute a clean-up job, so that all requests that have not been activated within a reasonable period (maybe two weeks?) are deleted from the DB.

2. Do you have any real-time monitoring of registrations?

If you can stay on top of the registration API calls, you can prevent most of the abuse attempts. Most of the time, you're trying to improve on the number of new users that are signing up. With monitoring/alerting, you can take defensive actions when the signup behavior starts looking suspicious. For example:

  • Sudden major spike in API calls without any trigger from your end (like new marketing campaigns or a blog post)
  • Too many registration attempts from a single IP or IP range
  • Observing the same values in the HTTP request header (assuming here the API call your app makes passes along some client-specific values and does not use a static request header)

3. Abuse prevention options

As I said in the beginning, CAPTCHA can be a second level where the first level is to have a throttling feature for the registration requests. With each new registration attempt from the same IP, you can exponentially take a longer time to respond. After too many attempts are observed and the response time is already long enough, you can start asking for the CAPTCHA.

Hopefully at this stage, you have abuse under control. But also be prepared to start blocking/temporarily banning API calls if CAPTCHA does not give the result you expect.

BTW, this and most other anti-abuse features will benefit from being able to configure your service on-the-fly, to play with different values/options while observing and analyzing the effects.

Cahit
  • 2,484
  • 19
  • 23