I have a mobile app (currently IOS and soon Android) which talks to a web service. There is no login and the data is not private. Basically, the app POSTs a marker (lon, lat
The simplest way to implement rate limiting on the server side is to just use a web server plugin/module. For example, if your service is running on apache, install and configure mod_evasive. This will allow you to rate limit based on IP address, service/URL, etc. Mod Evasive will be more effective than what you can implement on your own.
If you use keys, you need to have some kind of captcha based way for the client to get the keys upon signup. You could have it drop accounts for abusive users. Right, of course one parameter would be the timestamp which would be verified as recent and in the past on the server side. The key would encrypt the entire payload along with the timestamp, and be added as an additional parameter. Storing frequency of requests on a per-key basis ends up requiring some kind of round-robin database, unless you only check recency of last request.
No purely client-side rate limit will make any difference. Someone could discover your API on the web without ever even having seen your client. I doubt that a shared secret would be effective for long.
You will find plenty of web services that don't require a password and are merely rate limited... for example, the twitter API offers many rate-limited unauthenticated API services.
It is tricky, you don't expect anybody to tamper the data ... so your concern is not about integrity. And since you do not maintain any list of clients ... there cannot be any concern about Authenticity?
And for all the well know Webservice attacks (like DoS or replay attacks) you get firewalls that can prevent them. So I don't think you need to bother about them much.
But then you you don't want to send plain text data and want to make sure that your download app is what is pushing the data.
If you look at the approaches you are evaluating :
Secured Key : As I understand the server and the App are going to share the same Key and if I am correct all the apps on all the devices will share the same Key. And when the app pushes the data it hashes the Actual feed and sends across Actual feed + the hashed feed. On the server side you would use the Key and hash the actual feed and verify if it is matching with the hashed feed. And in my opinion this solution is mainly addresses the Data integrity aspect which is not a major concern for you. rgt! (And yes it will probably be easy to reverse engineer.)
In the above approaches server would need to store the Key So if your Key is compromised your whole service will be and it will be difficult to update all the apps with new key. Or else if the app generates a Key it will have to send the key on the wire along with the message as digest or something(like timestamp + some random number). Not so difficult to break.
Certificate: Even with certificates you get the same security .. but it is difficult to break but easy to steel :). If you are keeping a private Key with device (ofcourse then you will have to maintain a public key at the server). You will have to assign a private key per client and then the server needs to maintain the public key for all private keys assigned. If a private key is compromized only that single app can be red flaged and requested for an update.
So what is left is from an application development perspective you want to avoid fabricated data. For sake of preventing mischief The the only point to check such things is in the application logic. You will need to cache the last ten(or what even the optimum number is) feeds (comming from same IP)and have some sort of logic verify if there is a flaw.