6

This is a general question but its prompted by a fairly open API I have for a file storage service that needs to have its front door better locked down.

We have an API like POST '/signup' that just takes a username and password and creates a user. It is totally possible for someone to write a very simple script to call /signup with every letter combination that fits our username rules and effectively brick us from new signups.

I have not found a concise enumeration of all the possible signup security tricks, so I will start them now and ask for anyone to contribute what I have omitted or further implementation details on a particular item.

  • IP Throttling: For every signup, record the IP address and check it against a table of recent signup IPs to ensure number of signups and time since last signup at this IP is not suspicious. **

  • Other authorized login: Use verified email, phone number, or 3rd party OAuth logins

  • Human verification: Have the users complete a Captcha or some form of validation that is too computationally expensive for a script to manage

** IP throttling seems to be the only option that will not necessarily affect the client signup experience, although at the cost of implementing a new subsystem to orchestrate the storage and validation of IPs (Are there 3rd party services for this?). It also does not protect against the extreme case where a network of attackers (or attackers that can change public IP) distribute the attack across N IPs to make N usernames.

  • Is the script in PHP? PHP has a thing called a session id, and when you first start a session a legit session, you can call a function to create a unique id. Then in the $POST check routine if the session id is null drop it. If they didn't start the session in the normal way it won't have a session id. – cybernard Mar 31 '16 at 0:15
  • It is not, I should've included: It's a Node/Express app on EC2 behind an ELB. – user Mar 31 '16 at 0:37
2

You could use a tool like Fail2Ban against the API logs to block an IP for 5 minutes (or whatever you want) after 3 (or any number) of account creation attempts.

http://www.fail2ban.org/wiki/index.php/Main_Page

It would also be wise to know some common API requests that are made by brute force attempts that do not exist on your site and automatically blacklist IP's that make those requests (at least for 30 minutes or so).

Blacklisting at the IP layer based on well set triggers is a very low cpu-cost way to deal with Brute Force attempts. It's also wise to whitelist known good IP's in your infrastructure when you do this.

  • Good suggestion. Can't find any documentation on how to get it running with Node/Express or with Amazon's ELB but I'm sure its possible. For grins, here's the list of BS requests I've gotten on a single app server in 6 hours: pastebin.com/kSqDCHeg. – user Mar 30 '16 at 23:09
  • Just saw the pastebin link. NICE !!! – Trey Blalock Aug 25 '16 at 4:39
2

First off, if we're talking about a website, the idea of having a public API which is used to create users seems strange to me. Usually an account is manually created by the person that wants one, perhaps using a web page, and perhaps with a captcha. The ideas of API and captcha don't really go well together since APIs are called by Applications (thus the A in API), and captchas are designed to prevent applications from solving them.

If you really need to have a non-manual method for creating users (thus exposing the functionality in the API), you could potentially solve your problem by having a semi-public API instead. You would need to require the developers that plan to consume your API to register to receive an API key which is unique to that registered user. Any API call that performs write actions (such as creating a user) would need to provide a valid key. Now you can track everything that is done and if you see someone abusing your system, you can just shut them down, and even undo their abuse if you wish.

A common scenario where you may need to have an API for creating users is a mobile application. In this case you can attempt to make the API semi-public by generating an API token per installed mobile app. The token is passed to the app via encryption that only the app can decrypt, and that token can only be used to create a certain number of user accounts (1 or however many makes sense). This isn't perfect, as someone could theoretically decompile the application and attempt to extract the encryption keys, and if they did they could incorporate the entire handshake process into their script, but it should at least slow them down.

Of course you still can (and probably should) add firewall rules as well.

  • 1
    But even then, a web-only signup on my own interface would still require a human-verification component to make it any better than a public API.. – user Mar 30 '16 at 22:52
  • @user - I agree. Any web-only registration is still vulnerable to a sign-up bot, so a captcha is usually recommended. – TTT Mar 31 '16 at 1:38

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.