I have this webservice at work. For that webservice our department have developed a client to consume the webservice.
What we want to prevent is, that they develop any other client to consume it.
Is there any algorithm, practice that we can improve in our client and webservice communication to validate that the consuming client is our application?
I have an idea, that we can develop an encrypting algorithm about the time (5 seconds of grace) that must match with the calculated on server.
But i want to be sure, there is no best practice for that... or if it still a good idea...
(sorry about my english)
I think part of the point of web services (SOAP or REST based, for example) is to publish an interface that will let your service potentially be used by a variety of client implementations (interoperability is one of the motivations for web services).
If you want to lock your service to be used by your client, the only benefit of having it as a "web service" is probably the tools and libraries with which you've implemented it. You may want to consider whether this was worthwhile (it's possible indeed).
If you distribute your client application, chances are that whatever protection mechanism that may ensure the requests come from that client will have to be embedded with this client. Therefore whatever secret mechanism you embed will probably be only obfuscated to a certain point, but breakable by more advanced users.
What you are looking for is known as "authentication".
You need application authentication. For Web based application and services try looking into 2-legged OAuth. In OAuth You give out an id and a secret for every client app which accesses your service and every message is signed for extra security.
Related
I've read a lot of articles on this subject and they all suggest completely different things that I can't yet structure in my head.
I have one backend app (spring-boot + kotlin). I have nginx and one android (kotlin) mobile app uses backend api and of course Postgres. By the way backend app and postgres are packages in docker containers via docker-compose.
My task is to make the API of my backend service can only be used by this mobile application and no one else. But I also want it to be able to use the API if I have a Web application in the future.
I would be fantastically grateful if you could describe, in a few words, modern technology that could be used to accomplish my task.
For example:
Spring-security: a huge thing that you don't know what to do with, most likely you can use it to solve your problems, but it's overkill. But if you decide to use spring-security, this will help you {...}
...
By the way, I'm not against spring-security, I just really think it's too much for my task. But I'd be happy to hear your opinion.
Your Problem
My task is to make the API of my backend service can only be used by this mobile application and no one else. But I also want it to be able to use the API if I have a Web application in the future.
You have in hands a very hard task to complete. While not impossible it's very hard to accomplish with code written on your own or by trying to leverage security features on your framework of choice.
To understand why it's so hard you first need to understand the difference between who is in the request versus what is doing the request.
The Difference Between WHO and WHAT is Accessing the API Server
I wrote a series of articles around API and Mobile security, and in the article Why Does Your Mobile App Need An Api Key? you can read in detail the difference between who and what is accessing your API server, but I will extract here the main takes from it:
The what is the thing making the request to the API server. Is it really a genuine instance of your mobile app, or is it a bot, an automated script or an attacker manually poking around your API server with a tool like Postman?
The who is the user of the mobile app that we can authenticate, authorize and identify in several ways, like using OpenID Connect or OAUTH2 flows.
So think about the who as the user your API server will be able to Authenticate and Authorize access to the data, and think about the what as the software making that request in behalf of the user.
After you understand this idea and it's ingrained in your mindset, you will look into mobile API security with another perspective, and you will be able to see attack surfaces that you never though they could exist.
Possible Solution
I would be fantastically grateful if you could describe, in a few words, modern technology that could be used to accomplish my task.
I recommend you to read this answer I gave to the question How to secure an API REST for mobile app?, especially the sections Hardening and Shielding the Mobile App, Securing the API Server and A Possible Better Solution.
The best approach to solve your problem is to go with a Mobile App Attestation solution suggested in the answer I linked. A Mobile App Attestation needs to be able to work in tandem with your mobile app and backend in order for the backend to have a very high degree of confidence that what is making the request is indeed a genuine version of your mobile app, that hasn't been tampered with statically or at runtime, and it's not under a
MitM Attack
The Manipulator-in-the middle attack (MITM) intercepts a communication between two systems. For example, in an http transaction the target is the TCP connection between client and server. Using different techniques, the attacker splits the original TCP connection into 2 new connections, one between the client and the attacker and the other between the attacker and the server, as shown in figure 1. Once the TCP connection is intercepted, the attacker acts as a proxy, being able to read, insert and modify the data in the intercepted communication.
The MITM attack is very effective because of the nature of the http protocol and data transfer which are all ASCII based. In this way, it’s possible to view and interview within the http protocol and also in the data transferred. So, for example, it’s possible to capture a session cookie reading the http header, but it’s also possible to change an amount of money transaction inside the application context
Be aware that solutions to solve your problem that are specific to the backend or to the mobile app will not be able to achieve a very high degree of confidence in securing your API backend from serving requests not originated from your genuine mobile app, but it's better to have them then nothing.
Do You Want To Go The Extra Mile?
In any response to a security question I always like to reference the excellent work from the OWASP foundation.
For APIS
OWASP API Security Top 10
The OWASP API Security Project seeks to provide value to software developers and security assessors by underscoring the potential risks in insecure APIs, and illustrating how these risks may be mitigated. In order to facilitate this goal, the OWASP API Security Project will create and maintain a Top 10 API Security Risks document, as well as a documentation portal for best practices when creating or assessing APIs.
For Mobile Apps
OWASP Mobile Security Project - Top 10 risks
The OWASP Mobile Security Project is a centralized resource intended to give developers and security teams the resources they need to build and maintain secure mobile applications. Through the project, our goal is to classify mobile security risks and provide developmental controls to reduce their impact or likelihood of exploitation.
OWASP - Mobile Security Testing Guide:
The Mobile Security Testing Guide (MSTG) is a comprehensive manual for mobile app security development, testing and reverse engineering.
The easiest way probably is to define a shared secret on the phone and the backend service.
On the mobile phone, with each request, you send the secret, e.g., as an HTTP header.
On the backend, you need to implement a Filter (e.g., OncePerRequestFilter) that checks the request for the secret and compares it to the value stored in the backend.
I want to develop a (REST API) web app using Spring, and for the authentication/authorization I am thinking about using OAuth 2.0, but I am not sure whether OAuth is a good option or not.
some information about my app:
1 - completely RESTful API.
2 - microservice Architecture.
3 - using the API for both web pages (maybe SPA) and mobile apps(android and ios).
4 - the API will be used only by our developers (web site developers and mobile app developers), and never by other third-party developers (as far as I know the main purpose of OAuth is for third-party applications).
based on the given information, is it a good idea using OAuth instead of a custom Spring authentication/authorization server with JWT? if yes, what are the benefits?
some disadvantages and advantages from my past experience:
Disadvantages :
OAUTH authentication payload will contain : username, password, grant_type, client_secret and client_id.
The last two ones are specific for third-party login, do they make sense for your application and clients?
Spring OAUTH is a powerful library and will do a lot behind scenes. If you will need custom behavior, it will a little bit trickier to find the right hooks.
Development time took longer (both client and server) in comparison with simple username/password login.
Advantages :
The protocol is well documented, so you will have less overhead when documenting your application.
It will be easier to integrate with third parties (if ever is required).
P.S In your initial iteration you can start with simple login and add later third party integration(both can work together)
While prototyping out an API & SDK, I've run into this question with several plausible solutions. I'm looking for help with some of the high level architecture. In short, it is guaranteed that some consuming applications of the API are going to want to configure their own authentication providers.
Options that I've been munching on:
Keep resource server and authorization coupled but figure out some way to delegate authentication in one of the authentication providers in my auth manager to the client application.
This sounds promising until I realized that in the particular use case, it's actually necessary that even my providing application not know the user's credentials.
Separate the resource server and make each consuming application responsible for providing an authorization server, and set those endpoints as part of the configuration when registering the consuming app with the resource provider.
This feels like an uncomfortable inversion of what is often desired when using authorization_code grant types. It also would require any "default" authorization providers to be implemented by each consuming application.
Some kind of delegating authorization server that falls back to a default if a client hasn't provided endpoints for their own authorization server.
This would probably be a good solution, but I'm not sure how to do it the "spring-security-oauth2" way or if I'd have to implement a bunch of my own stuff.
Create a default auth server, and optionally allow consuming applications to point to whichever auth server they want.
This seems viable approach in that it offers lots of customization. My concern is, how do I enforce some kind of registry with the resource server? If the auth server is the server that approves consuming applications, but I don't want to let any consuming application implement its own auth server, just some of them. Otherwise non-trusted clients could end up approving themselves!?
In case this influences any guidance, my resource provider will need a fully inflated OAuth2Authentication object (which contains user details and client details).
This image mostly explains what I'm talking about, except I want multiple authorization servers and want to leave it to the consuming application to decide which authorization server to point at. How could I check on the resource-server side of things that the authorization server proxying the requests is an approved authorization server?
ADDENDUM:
I took a look at the existing implementation that's being used for this custom authentication case and I guess we're just reading a token off their session that gets set by their own login service and building their user each time off of that. This sort of customization is a problem in that we're removing customizations from the provider side of things in favor of handling that in the consuming applications. So, I'm looking for solutions so consuming apps can define their own authentication means, to the point of even providing users that the providing application doesn't persist (which leads me to think it may need to be an entire auth server).
That being said, this seems like a potentially unsustainable inverted model (IMHO, the provider should be the maintainer of users and authorization, not the consuming apps). So, I'll probably recommend a more business oriented change.
I believe I have finally come up with a secure and maintainable way of solving this.
Let consuming applications optionally register an authentication callback with the authorization server.
Require incoming authorization requests from that application to the authorization server on behalf of a user to include a token, that token should be stored by the consuming application as a means of referencing whichever user is actively causing the API call.
When an authorization code request is received by the authorization server from an application that has registered one of these callbacks, then POST to that application's registered authentication callback and include the token that was provided by the consuming application in the request.
The consuming application should take the token that was POSTed to it's registered authentication callback and look up the corresponding user, and return a response containing the full user object on whose behalf the providing application should operate (or some kind of error code if the token is invalid).
The authorization server should then generate an authorization code and return to the callback uri submitted with the authorization code request. This means we're back on track according to step 4 in the diagram in the original question. The remaining steps can be carried out as-is.
There is a remaining question of how this might be implemented to take advantage of as much of the spring-security-oauth2 framework as possible while still achieving this extension.
I'm currently building a RESTful API to our web service, which will be accessed by 3rd party web and mobile apps. We want to have certain level of control over API consumers (i.e. those web and mobile apps), so we can do API requests throttling and/or block certain malicious clients. For that purpose we want every developer who will be accessing our API to obtain an API key from us and use it to access our API endpoints. For some API calls that are not dealing with the specific user information, that's the only required level of authentication & authorization, which I call "app"-level A&A. However, some API calls deal with information belonging to the specific users, so we need a way to allow those users to login and authorize the app to access their data, which creates a second level (or "user"-level A&A).
It makes a lot of sense to use OAuth2 for the "user"-level A&A and I think I have a pretty good understanding of what I need to do here.
I also implemented OAuth1-like scheme, where app developers receive a pair of API key & secret, supply their API key with every call and use secret to sign their requests (again, it's very OAuth1 like and I should probably just use OAuth1 for that).
Now the problem that I have is how to marry those two different mechanisms. My current hypothesis is that I continue to use API key/secret pair to sign all requests to be able to access all API endpoints and for those calls that require access to user-specific information apps will need to go through OAuth2 flow and obtain access tokens and supply them.
So, my question to the community is - does it sounds like a good solution or there are some better ways to architect this.
I'd also appreciate any links to existing solutions that I could use, instead of re-inventing the wheel (our services is Ruby/Rails-based).
Your key/secret pair isn't really giving you any confidence in the authorship of mobile apps. The secret will be embedded in the executable, then given to users, and there's really nothing you can do to prevent the user from extracting the key.
In the Stack Exchange API, we just use OAuth 2.0 and accept that all we can do is cutoff abusive users (or IPs, in earlier revisions without OAuth). We do provide keys for tracking purposes, but they're not secret (and grant nothing of value, so there's no incentive to steal them).
In terms of preventing abuse, what we do is throttle based on IP in the absence of an auth token, but switch to a per-user throttle when there is one.
When dealing with purely malicious clients, we unleash the lawyers (malicious in our case is almost always violation of cc-wiki guidelines); technical solutions aren't sophisticated enough in our estimation. Note that the incidence of malicious clients is really really low (single digits in years of operation, with millions of daily API requests).
In short, I'd ditch OAuth 1.0 and switch your throttles to a hybrid of IP and user based.
I'm looking at having thousands of simultaneous connections from mobile phones to the server whereby anytime a user interacts with his cell phone, the data is sent and logged by the server. Also, anytime the server has new information for that user, the server can push that information without a browser refresh. I am wondering what is more stable and how you would build this?
A good real-time framework or infrastructure will have numerous APIs that should let you connect any device, no matter the technology, to the real-time server e.g. an iOS client library for iPhone and iPad, a JavaScript client library for numerous platforms including normal and mobile web, an Android compatible Java library and so on.
An interesting idea might be to choose which ever framework or real-time service suits your needs best and then using something like PhoneGap. But, as #rt2088 says, it depends if you need the notification app to be running as a service on the phone or as a standalone application.
The choice will also depend on whether you want to install, host, maintain and manage the scaling of your own real-time services or not. If not, there are a number of services out there who you could use so you can concentrate on building your application. If you do want to manage your own infrastructure then the Comet Maturity guide could be a good start. It's a little out of date but is still probably the best reference available.
the ability to push new content the
user based on his GPS location which
is "pinged" to our server. Based on
that, we deliver local content. What
frameworks are you talking about?
There are a number of real-time frameworks available at the moment. Some are hosted services and others require installation on your own hardware. The majority of them will come with a bunch of libraries in different technologies that make it easier to get up and running with them e.g. a JavaScript library that wraps the WebSocket object and also manages fallback for web browsers that don't support WebSockets.
I've just created a Real-Time Technologies Guide in which I've listed all the real-time technologies that I could think of and provided a bunch of tags associated with each.
wouldn't a javascript client library
cover all platforms if it is a web
appilcation?
If the application is a web application then yes, a JavaScript library would be all you need for the client application. The server side libraries that you require would depend on the real-time technology you choose.
Best solution to achieve this is to use the WebSocket communication. It is bidirectional asynchronous communication. Currently every browser supports this new standard and plenty of code snippets available. You just have to google it. There are many server and client side frameworks. choose the one best suits to your requirement.
The details of the WebSocket specification is available at -
Websocket specification
Do you need notification when user uses mobile browser of handset or the mobile handset itself (performing non-browser tasks)? Based on that, the framework to record user activity can be selected.