Stop api abuse before user is authenticated - rest

We have an Android app. Users need to login using sms based OTP before app can be used.
Our request for OTP is public API. Attackers have started to abuse this API. 10x more API calls as compared to actual users.
What are the different ways this can be prevented? Solution should work at scale with response time and server resources should not get impacted.

You could do some server-side throttling by IP address and/or telephone number. But a persistent abuser could have blocks of numbers and IPs available.
The best solution is to have your app sign the payloads you send to your backend. If an unsigned or incorrectly signed payload comes in, don't send an OTP.
For iOS there's attestation, for Android there's Play Integrity. These API's allow you to verify that a call to your backend originated from a genuine app.

Related

Single Authentication Scala (PlayFramework) + mobile app

There is a mobile application that requests a phone number and sends a code from SMS during authentication.
Now I have a request sent to the backend with a phone number that generates a request to the SMS service. The service issues a token, which is sent when the code is confirmed from SMS. If success, I issue a token that lives for a certain time.
It is necessary to do authentication on Scala +PlayFramework, for example, as in Whats'up, telegram, where the token has an unlimited lifetime.
I have been looking for information for a long time, which libraries to implement this, but I have not found a solution, I will be grateful to the advice.

Mobile app/API security: will a hardcoded access key suffice?

I'm building a mobile app which allows users to find stores and discounts near their location. The mobile app gets that information from the server via a REST API, and I obviously want to protect that API.
Would it be enough to hardcode an access key (128 bit) into the mobile app, and send it on every request (enforcing https), and then check if it matches the server key? I am aware of JWT, but I believe using it or other token-based approach will give me more flexibility but not necessarily more security.
As far as I can see the only problem with this approach is that I become vulnerable to a malicious developer on our team. Would there be a way to solve this?
First, as discussed many times here, what you want to achieve is not technically possible in a way that could be called secure. You can't authenticate the client, you can only authenticate people. The reason is that anything you put into a client will be fully available to people using it, so they can reproduce any request it makes.
Anything below is just a thought experiment.
Your approach of adding a static key, and sending it with every request is a very naive attempt. As an attacker, it would be enough for me to inspect one single request created by your app and then I would have the key to make any other request.
A very slightly better approach would be to store a key in your app and sign requests with it (instead of sending the actual key), like for example to create a hmac of the request with the key and add that as an additional request header. That's better, because I would have to disassemble the app to get the key - more work which could deter me, but very much possible.
As a next step, that secret key could be generated upon the first use of your app, and there we are getting close to as good as this could get. Your user installs the app, you generate a key, store it in the appropriate keystore of your platform, and register it with the user. From then on, on your backend you require every request to be signed (eg. the hmac method above) with the key associated with your user. The obvious problem is how you would assign keys - and such a key would still authenticate a user, and not his device or client, but at least from a proper keystore on a mobile platform, it would not be straightforward to get the key without rooting/jailbraking.But nothing would keep an attacker from installing the app on a rooted device or an emulator.
So the bottomline is, you can't prevent people from accessing your api with a different client. However, in the vast majority of cases they wouldn't want to anyway. If you really want to protect it, it should not be public, and a mobile app is not an appropriate platform.
YOUR PROBLEM
Would it be enough to hardcode an access key (128 bit) into the mobile app, and send it on every request (enforcing https), and then check if it matches the server key?
Well no, because every secret you hide in a mobile app, is not anymore a secret, because will be accessible to everyone that wants to spend some time to reverse engineer your mobile app or to perform a MitM attack against it in a device he controls.
On the article How to Extract an API key from a Mobile App by Static Binary Analysis I show how easy is to extract a secret from the binary, but I also show a good approach to hide it, that makes it hard to reverse engineer:
It's time to look for a more advanced technique to hide the API key in a way that will be very hard to reverse engineer from the APK, and for this we will make use of native C++ code to store the API key, by leveraging the JNI interface which uses NDK under the hood.
While the secret may be hard to reverse engineer it will be easy to extract with a MitM attack, and that is what I talk about in the article Steal that API key with a MitM Attack:
So, in this article you will learn how to setup and run a MitM attack to intercept https traffic in a mobile device under your control, so that you can steal the API key. Finally, you will see at a high level how MitM attacks can be mitigated.
If you read the article you will learn how an attacker will be able to extract any secret you transmit over https to your API server, therefore a malicious developer in your team will not be your only concern.
You can go and learn how to implement certificate pinning to protect your https connection to the API server, and I also have wrote an article on it, entitled Securing Https with Certificate Pinning on Android:
In this article you have learned that certificate pinning is the act of associating a domain name with their expected X.509 certificate, and that this is necessary to protect trust based assumptions in the certificate chain. Mistakenly issued or compromised certificates are a threat, and it is also necessary to protect the mobile app against their use in hostile environments like public wifis, or against DNS Hijacking attacks.
Finally you learned how to prevent MitM attacks with the implementation of certificate pinning in an Android app that makes use of a network security config file for modern Android devices, and later by using TrustKit package which supports certificate pinning for both modern and old devices.
Sorry but I need to inform you that certificate pinning can be bypassed in a device the attacker controls, and I show how it can be done in the article entitled Bypass Certificate Pinning:
In this article you will learn how to repackage a mobile app in order to make it trust custom ssl certificates. This will allow us to bypass certificate pinning.
Despite certificate pinning can be bypassed it is important to always use it to secure the connection between your mobile app and API server.
So and now what, am I doomed to fail in defending my API server... Hope still exists, keep reading!
DEFENDING THE API SERVER
The mobile app gets that information from the server via a REST API, and I obviously want to protect that API.
Protecting an API server for a mobile app is possible, and it can be done by using the Mobile App Attestation concept.
Before I go in detail to explain the Mobile App Attestation concept is important to we first clarify an usual misconception among developers, the difference between the WHO and the WHAT is accessing your API server.
The Difference Between WHO and WHAT is Accessing the API Server
To better understand the differences between the WHO and the WHAT are accessing an API server, let’s use this picture:
The Intended Communication Channel represents the mobile app being used as you expected, by a legit user without any malicious intentions, using an untampered version of the mobile app, and communicating directly with the API server without being man in the middle attacked.
The actual channel may represent several different scenarios, like a legit user with malicious intentions that may be using a repackaged version of the mobile app, a hacker using the genuine version of the mobile app, while man in the middle attacking it, to understand how the communication between the mobile app and the API server is being done in order to be able to automate attacks against your API. Many other scenarios are possible, but we will not enumerate each one here.
I hope that by now you may already have a clue why the WHO and the WHAT are not the same, but if not it will become clear in a moment.
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.
OAUTH
Generally, OAuth provides to clients a "secure delegated access" to server resources on behalf of a resource owner. It specifies a process for resource owners to authorize third-party access to their server resources without sharing their credentials. Designed specifically to work with Hypertext Transfer Protocol (HTTP), OAuth essentially allows access tokens to be issued to third-party clients by an authorization server, with the approval of the resource owner. The third party then uses the access token to access the protected resources hosted by the resource server.
OpenID Connect
OpenID Connect 1.0 is a simple identity layer on top of the OAuth 2.0 protocol. It allows Clients to verify the identity of the End-User based on the authentication performed by an Authorization Server, as well as to obtain basic profile information about the End-User in an interoperable and REST-like manner.
While user authentication may let the API server know WHO is using the API, it cannot guarantee that the requests have originated from WHAT you expect, the original version of the mobile app.
Now we need a way to identify WHAT is calling the API server, and here things become more tricky than most developers may think. The WHAT is the thing making the request to the API server. Is it really a genuine instance of the mobile app, or is a bot, an automated script or an attacker manually poking around with the API server, using a tool like Postman?
For your surprise you may end up discovering that It can be one of the legit users using a repackaged version of the mobile app or an automated script that is trying to gamify and take advantage of the service provided by the application.
Well, to identify the WHAT, developers tend to resort to an API key that usually they hard-code in the code of their mobile app. Some developers go the extra mile and compute the key at run-time in the mobile app, thus it becomes a runtime secret as opposed to the former approach when a static secret is embedded in the code.
The above write-up was extracted from an article I wrote, entitled WHY DOES YOUR MOBILE APP NEED AN API KEY?, and that you can read in full here, that is the first article in a series of articles about API keys.
Mobile App Attestation
The role of a Mobile App Attestation solution is to guarantee at run-time that your mobile app was not tampered with, is not running in a rooted device, not being instrumented by a framework like xPosed or Frida, not being MitM attacked, and this is achieved by running an SDK in the background. The service running in the cloud will challenge the app, and based on the responses it will attest the integrity of the mobile app and device is running on, thus the SDK will never be responsible for any decisions.
Frida
Inject your own scripts into black box processes. Hook any function, spy on crypto APIs or trace private application code, no source code needed. Edit, hit save, and instantly see the results. All without compilation steps or program restarts.
xPosed
Xposed is a framework for modules that can change the behavior of the system and apps without touching any APKs. That's great because it means that modules can work for different versions and even ROMs without any changes (as long as the original code was not changed too much). It's also easy to undo.
MiTM Proxy
An interactive TLS-capable intercepting HTTP proxy for penetration testers and software developers.
On successful attestation of the mobile app integrity a short time lived JWT token is issued and signed with a secret that only the API server and the Mobile App Attestation service in the cloud are aware. In the case of failure on the mobile app attestation the JWT token is signed with a secret that the API server does not know.
Now the App must sent with every API call the JWT token in the headers of the request. This will allow the API server to only serve requests when it can verify the signature and expiration time in the JWT token and refuse them when it fails the verification.
Once the secret used by the Mobile App Attestation service is not known by the mobile app, is not possible to reverse engineer it at run-time even when the App is tampered, running in a rooted device or communicating over a connection that is being the target of a Man in the Middle Attack.
The Mobile App Attestation service already exists as a SAAS solution at Approov(I work here) that provides SDKs for several platforms, including iOS, Android, React Native and others. The integration will also need a small check in the API server code to verify the JWT token issued by the cloud service. This check is necessary for the API server to be able to decide what requests to serve and what ones to deny.
SUMMARY
In the end, the solution to use in order to protect your API server must be chosen in accordance with the value of what you are trying to protect and the legal requirements for that type of data, like the GDPR regulations in Europe.
DO YOU WANT TO GO THE EXTRA MILE?
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.

Design for Authentication schema for A WebService called by Mobile Client

I've a (Json) WebService that have multiple methods.
I need to call these methods in a Mobile App. And need to add authentication schema to this Service.
Note, there's a Login screen in the Mobile app.
What is the best way to accomplish that?
One suggest (but I don't desire) is:
Have the All WebService methods to have two extra Parameters (UserName and Password), thus send the authentication with each request.
Other Suggestion might be:
What If I used OAuth authentication schema; which as I could understand is to send Username&password once, and then have the server send the client some token and then the client uses it in subsequent calls.
Please suggest me!
Sending username/email+password with every request requires you to persist both within the application which is bad.
OAuth is the perfect way to implement authentication for mobile devices. Following standards is good.
The bottom line is that it doesn't make sense to make any short-term expiring token for the app (unless it's a banking app or an app accessing CIA/FBI/UNB facilities).

Best practices for securing API credentials as part of an iPhone app

The apps that I build frequently have 'social media service' requirements; e.g.
Twitter
bit.ly
Facebook
For most of these services, I need to have an API key of some sort. I'm trying to work out the best way of including these API keys in the application binary. The desired level of security depends on the possible attacks that can be conducted by malicious attackers.
Twitter
I have an xAuth-enabled key and secret. Both need to be used by the iPhone app.
Fallout from attack
Malicious users could post twitter status updates masquerading as coming from my app. There is no twitter account to hijack and start posting status updates on.
bit.ly
I have a username, password and API key.
To login to the website and access analytics, the username and password are required.
To create links via the API, only the username and API key are required by my iPhone apps. The password will not be in the app in any form.
Fallout from attack
Malicious users could create links on my bit.ly account. They would need to do a separate attack to brute-force or otherwise gain the password to login to the account.
For both of those services, the potential for harm doesn't seem too great. But for other services, it could be much worse.
I can just define the API credentials as strings in the header or in-line in the code, but then it's vulnerable to someone using strings on the application to see what's in it.
I could then start doing silly concatenation / xor-ing in the code to recreate the API key in memory, and the attacker would have to do a bit more work to recover any keys in the binary. My concern with that is that I'm not a cryptographer and would create an embarrassingly weak form of obfuscation there.
What better suggestions do people have?
The attacker can just sniff your traffic and extract the secret from there. So any obfuscation is easily circumvented.
Even SSL won't help much, since you can intercept the networking API which receives the unencrypted data.
The secure way to solve this is create your own server, keep the secret stuff server side, and use your own server from your app, and the server then relays to the other webservice. This way the attacker never has access to the secret.
A good suggestion is not to worry about it. There are plenty of apps that store their API keys in plain text. The point is you need a lot of different bits of information to construct an access token.
As long as you're not storing username+password combos in plain text on the file system or transmitting them over the network without SSL/HTTPS etc then you're fine.

Authenticating users in iPhone app

I'm developing an HTTP api for our web application. Initially, the primary consumer of the API will be an iPhone app we're developing, but I'm designing this with future uses in mind (such as mobile apps for other platforms). I'm trying to decide on the best way to authenticate users so they can access their accounts from the iPhone. I've got a design that I think works well, but I'm no security expert, so I figured it would be good to ask for feedback here.
The design of the user authentication has 3 primary goals:
Good user experience: We want to allow users to enter their credentials once, and remain logged in indefinitely, until they explicitly log out. I would have considered OAuth if not for the fact that the experience from an iPhone app is pretty awful, from what I've heard (i.e. it launches the login form in Safari, then tells the user to return to the app when authentication succeeds).
No need to store the user creds with the app: I always hate the idea of having the user's password stored in either plain text or symmetrically encrypted anywhere, so I don't want the app to have to store the password to pass it to the API for future API requests.
Security: We definitely don't need the intense security of a banking app, but I'd obviously like this to be secure.
Overall, the API is REST-inspired (i.e. treating URLs as resources, and using the HTTP methods and status codes semantically). Each request to the API must include two custom HTTP headers: an API Key (unique to each client app) and a unique device ID. The API requires all requests to be made using HTTPS, so that the headers and body are encrypted.
Current strategy:
My plan is to have an api_sessions table in my database. It has a unique constraint on the API key and unique device ID (so that a device may only be logged into a single user account through a given app) as well as a foreign key to the users table.
The API will have a login endpoint, which receives the username/password and, if they match an account, logs the user in, creating an api_sessions record for the given API key and device id. Future API requests will look up the api_session using the API key and device id, and, if a record is found, treat the request as being logged in under the user account referenced by the api_session record.
There will also be a logout API endpoint, which deletes the record from the api_sessions table.
Does anyone see any obvious security holes in this?
I agree with the oAuth comments - you can of course make oAuth work nicely on an iPhone - the UX is totally up to you. There are mechanisms (jQuery) to pull back the PIN from oAuth and use it (without the user re-typing the PIN into the app). That reduces the UX to
1) Display web page (in embedded control)
2) user enters user and password and presses button
3) oAuth response page is parsed automatically.
This twitter oAuth implmentation does that http://github.com/bengottlieb/Twitter-OAuth-iPhone using a pre-existing oAuth library.
However, back to your original question. That looks fine. The only item you don't mention, is that you need to provide a mechanism on the web app to allow the user to logout/deauthorize a device session (in case they have lost their device).