views:

172

answers:

5

Hey everyone, I run an image hosting website and I'm designing an API for it. My concern is that I don't want anyone to be able to do something like:

while(true) { 
    Upload();
}

and spam/DoS the site.

My current solution is to limit all IP addresses to a certain amount of uploads per day/hour. I believe this will work fine for desktop applications that will use the API, but for websites that wish to use it, all the users will have the same IP (the server's).

I suppose the best solution would be to have user accounts that authenticate with the API, and then ban each account if they abuse it. The problem with this is that my site has no user accounts at all, it's all completely anonymous.

What else can be done? I would like to keep things as open as possible, while at the same time have the ability to ban users/IPs who are obviously abusing the service.

+2  A: 

Check out OAuth.

Noon Silk
+5  A: 

If you don't want to implement user accounts, how about having those that want to use the api sign up for an api key/secret, which you can use to rate limit with.

Olivieri
+1 for API keys.
LiraNuna
LiraNuna: I suggest you also look into OAuth. It is a specification for dealing with all of this (API keys and so on) correctly.
Noon Silk
OAuth is a way to implement API keys. Since the OP did not ask for a service to do it for him, but an idea of how to manage it, I believe this is a better answer.
LiraNuna
Doesn't that conflict with "it's all completely anonymous"? I suppose you only have the info for the website, not the user...but still....
Mark Brackett
A: 

At one company I worked for, we implemented throttling for all non-paying customers, with a limit of a certain number of requests per day, theoretically configurable per API endpoint. If You had to supply a unique ID as your application key in each request, in the QueryString for lightweight APIs or in the POST request XML for more complex APIs. For end-users not using a public API, you could pass an authentication token instead.

If you supply a public API without requiring some kind of authentication or authorization, you'll have to resort to IP-address based throttling. But it's not hard to create a lightweight provisioning web page that allows people to sign up for API access.

Your application logic can throttle based on number of requests, like we did, or daily bandwidth, like Flickr does.

JasonTrue
A: 

Require a token to upload, and restrict the token with a CAPTCHA. Consuming code would be something like:

// 1st request
var uploadToken = api.RequestToken(sessionIdFromUser);
if (uploadToken.RequireChallenge) {
   // requires challenge due to per IP limiting
   // uploadToken.Captcha could be a URL
   DisplayView(uploadToken.Captcha, uploadToken.SessionId); 
   return;
}
api.Upload(uploadToken, captchaFromUser, byte[]);
Mark Brackett
A: 

As others have mentioned on this thread, API keys is often the way to go in such situations. The fact that your site has no user accounts doe not matter: an API key identifies an application, and not a user. (In fact, if your site did have users, you woud need separate mechanisms to identify the app and the user in an API call - this is where OAuth is very helpful).

If you do not want to create your own developer registration process, API key issuing process, throttling code, etc., I would encourage you to take a look at my company, WebServius (www.webservius.com), that provides a hosted API management layer on top of an API you provide.

Eugene Osovetsky