Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

REST - How to restrict access for not authorized client software

here is the challenge:

The service-/business layer has a REST (JSON) interface. There are two kinds of clients which can call the API: The webapp, which is running in a browser and a mobile-app (Android). Both of them are public. Everyone who uses the authorized (!) webapp or the authorized (!) mobile-app should have access to the resources. All unauthorized clients (scripts, for instance) should be prohibited.

Note: There are no limitations how many or which users have access to the service layer -> client public key certificates probably can't be used. Only the the client software has to be authorized.

In my opinion the only one solution is "by obscurity".

Ideas:

  • Load a random JS-function (let's call it "the challenge") from the server, which is executed in the browser (or app), fingerprints the browser in a specific way (browser flaws?), computes a result and send the result back with every REST-API call.

Do you have any further ideas or suggestions?

Thank you in advance & sorry for my bad english

Edit:

My question has nothing to do with user authentification and/or authorization but client-software authentification + authorization.

The background of my question is, that there is a RESTful back-end for my own applications (android + web) and I don't want that someone creates his own client-software on top of it. The reason for this is because it's a commercial website/application which provides some data which was quite expencive to collect. I'd like to promote the website and the mobile-app and not the RESTapi (or some third-party competitor).

like image 529
kalamar Avatar asked Dec 27 '12 17:12

kalamar


2 Answers

Unfortunately, my response is that you should simply never trust the client application(s).

While there are various ways to create a trust relationship with the client you have distributed, all of them can be hacked, cracked, or bypassed. Never trust any data coming from outside your server. Ever. Never rely on connections to be coming from your client or a major web browser. Everything can be spoofed with enough time and effort.

Some good examples of issues like this in the industry are easily seen from things like gaming, where even with routines to check for memory hacks and other approaches, eventually even services with huge budgets like World of Warcraft often see either hacks of their client appear or outright client emulators capable of sending commands the normal client would not. Relying on your client software to remain secure and only ever send proper data to your server is a recipe for disaster. Always validate server side if it is for something important. Always properly escape/parameterize data. Use whitelist models, and preferably use symbol table lookups based on user input instead of user data itself where appropriate. Etc. Client side validation should only ever be seen as helping the user, not as something secure.

If you are simply going for "good enough" then you may have some options to help reduce the likelihood of seeing this happen, such as a security through obscurity solution like you proposed, but you should never rely on it not happening, even then.

One solution is to basically not include the major functionality of the client within the client, but instead send it from the server (javascript/etc) at runtime, with a different fingerprint for each time you send your logic package to the client, possibly with a range of different logic routines, with one randomly picked. You can then timeout the packages, track which user accessed which package, and have the package return telemetrics which you also use to help maintain security. Any mismatch between returned logic and what was sent with the fingerprint can immediately be assumed to be a spoof or hack attempt. Ultimately, however, all of this can still be beaten (a relatively rudimentary example like this can be beaten rather easily by someone determined, especially if you don't have runtime memory security).

There are a number of ways to deal with man in the middle (MITM) attacks, where someone is trying to intercept data, but none of them can fully account for a compromised endpoint.

like image 89
taswyn Avatar answered Nov 15 '22 12:11

taswyn


Web-servers typically support the concept of a "session". When a Web browser connects, a session is created on the server which returns a session ID (as a HTTP cookie usually). The web browser then sends that session ID cookie to all subsequent requests to the server.

Using this mechanism, a lot of programming languages / framework have an authentication / authorization module, which allows the user to authenticate himself (with a username and password typically). Once the identity of the user is validated, the session is updated with the ID of the user). The server code then checks the user ID from the session for each request to make sure the user is authenticated / allowed to issue the request (whether it's a HTML page view or API GET/POST).

Things can be a little different for an Android (or iOS...) app, but the idea is similar: have the user authenticate themselves once, give the client a "secret token" which is mapped in the server with the user record. Then this token is passed for all request sent by the client.

You can use a home grown library for that or a more standard one like OAuth2.

like image 6
Christophe L Avatar answered Nov 15 '22 12:11

Christophe L