Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How To Secure Web Service Without Login

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) and GETs the nearest 25 markers to display on a map.

It's a very trivial app and I cannot imagine anyone putting great effort into abusing the web service. However, I can see there is fun for someone in POSTing many markers. What most concerns me is someone running a script that pushes many requests (using expensive bandwidth and making nonsense of my app data).

I am slowly reaching the conclusion this cannot be secure. The best answer is "do not do this". Do not provide a web service without authentication. Not many services are so open. Google's You Tube API is open but most are not. Unfortunately, I have no choice. So after days of looking at this here's my thinking. Be aware I am very far from a security expert and I am confident my approach could be improved upon. But it might point you in the right direction. Hopefully, someone more experienced might chime in and correct/improve upon this. I found this article and comments particularly helpful.

Message Level Security

I will secure the msgs with a hash encryption. The clients and web service all retain a copy of a shared secret which is used as a salt to create a hash from the URL and all the POST arguments. The hash is passed as an additional argument and the hash is rebuilt and compared at the other end (using the shared key as a salt). This is pretty good until you understand that any mobile client code can be reverse engineered in minutes. At which point this line of defense is utterly useless.

Client Measures

The client includes rate limiting of messages as a measure to restrict the number of messages sent by honest users. Yet again this is useless against an attacker who jailbreaks the mobile device.

Server Side Security

So the server side must have as much additional security measures as possible, to stand alone on the assumption that your client (and shared secret) is compromised. Here is what I have:

One msg arg is a UTC time which is used to limit replay attacks. This should prevent an attacker from firing the same msg at the server repeatedly.

The server performs rate limiting by IP. Yes, IPs are easily spoofed and proxy switching is childs play but everything helps when you have so little.

Of course, the server strictly validates all arguments, uses parametised queries and doesn't return exceptions.

Transport Level Security

Unfortunately, I am fairly confident that issuing individual client SSL certs is not possible without a registration process. And because I am using the msg hash check (and my data is not private) I am not entirely sure what SSL brings to the table. However, I will probably use SSL (with one app wide cert) because it adds another level of security that is easily and cheaply deployed (albeit at a cost of additional connection time for every msg).

The Gaping Great Big Hole In My Approach

I am warned that should the app become popular that someone will compromise the shared secret on the client. Just because they can and they will probably post it on the internet. So really it all comes down to the server side. Unfortunately, I have no way to identify and block an attacker. This I would dearly love.

A Final Plea

After days of research this is all I have. But I want more. I would particularly appreciate any ideas to beef up the server side. So, I have put all my SO points up as a bounty. Yes sir, all 97 points!

like image 305
Polly Avatar asked Aug 12 '12 15:08

Polly


People also ask

Does Web service can be made secure?

Security is critical to web services. However, neither XML-RPC nor SOAP specifications make any explicit security or authentication requirements.

What kind of security is needed for Web services?

The key Web services security requirements are authentication, authorization, data protection, and nonrepudiation.

What does authorization mean in terms of web service security?

Authorization (also known as access control) is granting access to specific resources based on an authenticated user's entitlements. Entitlements are defined by one or several attributes.


2 Answers

Actually in your particular case, since it is currently an iOS only app, there is a solution.

  1. After the user downloads and runs the app for the first time, the app hits a /access_token/create API that comes up with a GUID and relays it back to the Application via Apple's Push Notifications.

  2. App stores this access_token, and uses it on all subsequent requests. Your actual API's can rate limit on the basis of the access_token.

Basically, you let Apple do all the hard work of ensuring that the initial request came from an actual iOS device.

Extending this to Desktop clients is possible, but somewhat ruins the UX. Just change step 1 to allow /access_token/create to accept arbitrary requests, and if the request is not from a iOS device, then force the user to verify their email address/solve a captcha etc before issuing them an access_token.

Android devices (not really familiar with them) may have a similar Push Notification mechanism, in which case you can use that, or may not have a Push Notification mechanism, in which case you can subject your Android users to the inconvenience listed above.

like image 149
Manav Avatar answered Sep 20 '22 19:09

Manav


I've heard about this idea once, when talking about finding a global solution to SPAM problem: force your client to perform some time-taking computation.

To be precise: find some computational algorithm, that can compute some z for a pair of x and y in a blink of an eye, but it takes some considerable amount of time to compute z being given only x. I can not provide actual algorithm but I am sure that there are plenty of them that would much this criteria.

Now the whole procedure should look as follows:

  1. Upon first client request generate some session_id and for this session_id a pair of x and y.
  2. Provide your client with session_id and x.
  3. Client can start calculations as soon as it receives data (in some background thread not related to user interactions).
  4. To request markers, client must provide session_id and calculated z.
  5. You can quickly verify if client's z is all right, for you already have x and y that let you easily do it.
  6. (option 1) For each session_id store how much/often it is being requested. The moment you suspect it is being abused - force regenerating x and y.
  7. (option 2) Force new x and y upon each consecutive request for a session_id.

Choosing between 6 and 7 is actually tweaking that depends on the complexity of algorithm vs. expected 'fair' use of marker database. If your estimates are good - the evil client should never obtain too much data or overload your server.

Hope it helps.

like image 31
Kuba Wyrostek Avatar answered Sep 21 '22 19:09

Kuba Wyrostek