0

Context

I'm currently in the works of creating a public mobile application. This application will be made available through the App Store and Google Play Store. The user will be able to perform certain actions in the application, which will then be posted to an API. The application will be made with Xamarin Forms.

Question

I want to secure this API to prevent anyone other than the App from making any post requests. From what i have read the best way to go about this would be to implement an OATH2 flow. However; i wouldn't like for a user to have to sign-in or register to any type of service.
How would i go about validating the post requests that come into the API and make sure that it's not someone that is impersonating my mobile application?

Things i have thought of:

  • Api-keys or clientsecrets. As it seems there are pretty easy to extract from a mobile app.
  • Certificate validation. (Couldn't find much on this for mobile client - server architecture)
  • Generating some type of checksum over the contents that i can validate serverside. However the code for this would have to be available client side or there would have to be an endpoint providing the checksum. But this would just move the problem imo.
  • ?

Any and all critic and feedback is welcome. i do apologize if there's anything obvious that i have missed during my research on this matter.

Thank you for your time.

JohnSolid
  • 11
  • 4
  • Short answer: there's nothing you can do. Never trust user input, always validate everything you receive – Camilo Terevinto Aug 15 '20 at 09:32
  • Most people these days are using a certifcate with TLS 1.2 for authentication. Then install the same certificate on client and server. – jdweng Aug 15 '20 at 09:37
  • @CamiloTerevinto Thankyou for your quick answer. Yes validating is definitly something that will be done. However, an attacker can send valid data that will be validated, but is infact not genuine and not provided by the app. – JohnSolid Aug 15 '20 at 09:38
  • About certificate use certificate pinning for keys I use firebase config so I retrieve api keys, about the checksum not really sure if you need it if certificate pinning is there since it doesn't allow man in the middle – PedroAGSantos Aug 15 '20 at 09:39
  • 1
    And anyone can very easily decompile your app, see the full source code and do whatever they want with it. Yes, it's a known problem that has no practical solution - obfuscators can only make the process a bit more tedious but the OS still needs to be able to execute the code. It all depends on what your app does and how important it is or how important is the data it deals with. This is one of the reasons why major vendors just embed web views in their apps and everything is provided from the server as HTML – Camilo Terevinto Aug 15 '20 at 09:43
  • @CamiloTerevinto this seems like a good solution. However wouldn't the source of this webview also be publicly available for anyone as we would run into the same problem as above? We cant validate it is actually the app requesting the webview, right? Wouldn't the attacker be able to load the webview in a browser and then sitll get access to the necessary information to send a request to the api? or simply create a post request in the console? $.ajax etc.... – JohnSolid Aug 15 '20 at 09:52
  • That's all correct, and normally mitigated enough by hiding everything behind a login screen. I don't even remember the last time I installed some app that didn't require me to login :) – Camilo Terevinto Aug 15 '20 at 09:55
  • @PedroAGSantos Wouldn't a possible attacker be able to capture the certificate from the device and add this to their own requests? – JohnSolid Aug 15 '20 at 09:56
  • @CamiloTerevinto Thankyou for thinking with me, really do appreciate it. It's an application that has to do with infomration about the users health and i want it to be as anonymized as possible, to prevent any and all possibilities of linking the data to actual persons. – JohnSolid Aug 15 '20 at 09:58
  • please read this and you will understand https://www.nowsecure.com/blog/2017/06/15/certificate-pinning-for-android-and-ios-mobile-man-in-the-middle-attack-prevention/#:~:text=By%20design%2C%20apps%20generally%20trust,server%20and%20kills%20the%20connection. – PedroAGSantos Aug 15 '20 at 10:01
  • That's... not at all a correct approach. In fact, you could even break quite a few laws by dealing with personal health data in unsecure manners. Do add authentication, use TLS, and anonymize the data in the database, there are ways of doing this securely – Camilo Terevinto Aug 15 '20 at 10:02
  • @CamiloTerevinto Thus my question as i want to go at this the best (and correct) way. Data that will be transmitted will obviously be encrypted using someform of public private key encryption, and TLS will definitly be used. However as i said i dont want anyone to register in order to use the application. As registering leads to a user pool which potentially could me matched to the data pool... So we're talking strict anonymized data. The data will be saved for a public health instituion so we are allowed to request and save it, just a matter of how we do this the correct way. – JohnSolid Aug 15 '20 at 10:07
  • I am in no way an expert, so I'd highly suggest you to consult with someone more appropriate, but I'd find it very weird if you could legally do this without user authentication – Camilo Terevinto Aug 15 '20 at 10:48
  • @CamiloTerevinto yes the whole thing will be legally vetted so i have no worries of doing anything that isn't allowed by our local laws. Why should it be illegal if we don't ask a user to identify? We don't need to know who they are. We don't want to know who they are. The data is not up for collecting. Simply transmitting. Once the data has been transmitted there is no way of finding out where it came from. Nonetheless thank you for the positive critisism and feedback. – JohnSolid Aug 15 '20 at 11:23
  • It's not about identifying the user, but protecting the user's data. The requirements depend on the target market and what data your system will store (both in servers and user devices) – Camilo Terevinto Aug 15 '20 at 11:28

2 Answers2

0

Check the following for android: https://developer.android.com/training/safetynet/attestation

The SafetyNet Attestation API provides a cryptographically-signed attestation, assessing the device's integrity. In order to create the attestation, the API examines the device's software and hardware environment, looking for integrity issues, and comparing it with the reference data for approved Android devices. The generated attestation is bound to the nonce that the caller app provides. The attestation also contains a generation timestamp and metadata about the requesting app.

For iOS, you can check the: https://developer.apple.com/documentation/devicecheck

As mentioned in the documentation, non are foolproof and should be joined with other security measures, but it's better than nothing nonetheless.

Athanasios Kataras
  • 25,191
  • 4
  • 32
  • 61
0

The Difference Between WHO and WHAT is Accessing the API Server

From what i have read the best way to go about this would be to implement an OATH2 flow.

OAuth2 only identifies who is in the request, not what is doing the request.

This is a common misconception among developers of any seniority, therefore I will link you to an article I wrote that has a section dedicated to explain this. 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.

Your Questions/Affirmations

I want to secure this API to prevent anyone other than the App from making any post requests.

And about GET request?

Depending on the data your mobile is asking to be delivered by the API server, the GET request may have the same degree of importance in terms of security then any POST request.

Let's say you app is doing GET requests to get sensible data like PII(Personal Identifiable Information), then without them being protected you are just opening your API server to be easily abused by attackers, and this results in the so called data breaches that can have a huge legal and financial impact for the business and their customers. For example in Europe with GDPR a data breach will have huge fines, specially when they conclude that the API was not properly protected to avoid automated data extraction.

Anyone can learn how to perform a MitM(Man in the Middle) attack to see how the mobile app does the API requests in order to automate them. I wrote the article Steal that Api Key with a Man in the Middle Attack that illustrates how easy a MitM attack can be done:

In order to help to demonstrate how to steal an API key, I have built and released in Github the Currency Converter Demo app for Android, which uses the same JNI/NDK technique we used in the earlier Android Hide Secrets app to hide the API key.

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.

However; i wouldn't like for a user to have to sign-in or register to any type of service.

Well then you are left with only one way of protecting the API request, and is to know what is doing the request, and now you bought yourself a very hard problem to solve, but not an impossible one.

Your Solutions

API Keys or Client Secrets

Things i have thought of:

Api-keys or clientsecrets. As it seems there are pretty easy to extract from a mobile app.

They are indeed very easy to extract, but you can make them harder(but not impossible) to extract by static binary analysis as I explain in the article How to Extract an API key from a Mobile App with Static Binary Analysis:

The range of open source tools available for reverse engineering is huge, and we really can't scratch the surface of this topic in this article, but instead we will focus in using the Mobile Security Framework(MobSF) to demonstrate how to reverse engineer the APK of our mobile app. MobSF is a collection of open source tools that present their results in an attractive dashboard, but the same tools used under the hood within MobSF and elsewhere can be used individually to achieve the same results.

Spoiler alert is that the best way to hide secrets from the above article is by using the JNI/NDK interface to hide them in native code:

Using Android Studio 2.2 and higher, you can use the NDK to compile C and C++ code into a native library and package it into your APK using Gradle, the IDE's integrated build system. Your Java code can then call functions in your native library through the Java Native Interface (JNI) framework.

Well now you just use a MitM attack to extract them and we are back to square zero? Well not exactly, because more layers of defense you apply, more the attacker needs to peel and be willing to spend the time on it, but much more can be done to upset them.

Certificate Pinning

Certificate validation. (Couldn't find much on this for mobile client - server architecture)

You can't find because certificate pinning is usually only done by the mobile app as I show in the article Securing HTTPS with Certificate Pinning:

In order to demonstrate how to use certificate pinning for protecting the https traffic between your mobile app and your API server, we will use the same Currency Converter Demo mobile app that I used in the previous article.

In this article we will learn what certificate pinning is, when to use it, how to implement it in an Android app, and how it can prevent a MitM attack.

So why not doing the same sever side? Well because once the app is release anything on it is public, therefore the certificate private key you would to ship with the app to allow the API server to pin against would be easily extracted with static binary analysis or during runtime with an instrumentation framework like 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.

I can imagine you now looking where is the link to the my article with an example of using Frida? Sorry, but I don't have yet an article with a Frida example :(

Digitally Signing Requests with HMAC

Generating some type of checksum over the contents that i can validate serverside. However the code for this would have to be available client side or there would have to be an endpoint providing the checksum. But this would just move the problem imo.

Yes you are correct, the problem would have to have the code in client side, but having an endpoint providing the checksum would only move your problem into two backends, because then you would need to ensure that the checksum endpoint would only sign request from your mobile app ;)

HMAC:

In cryptography, an HMAC (sometimes expanded as either keyed-hash message authentication code or hash-based message authentication code) is a specific type of message authentication code (MAC) involving a cryptographic hash function and a secret cryptographic key. As with any MAC, it may be used to simultaneously verify both the data integrity and the authenticity of a message.

Other Solutions

How would i go about validating the post requests that come into the API and make sure that it's not someone that is impersonating my mobile application?

As I said before you should not limit this to POST requests, instead you should validate that any request to the API server is indedd from *what you expect, your genuine and untampered mobile app.

Android SafetyNet

This is often the one recommended, and is a very good starting point, but it's not designed to be used as a stand-alone defence, as per Google own words:

The goal of this API is to provide you with confidence about the integrity of a device running your app. You can then obtain additional signals using the standard Android APIs. You should use the SafetyNet Attestation API as an additional in-depth defense signal as part of an anti-abuse system, not as the sole anti-abuse signal for your app.

You can read my answer to the question Android equivalent of ios devicecheck for a more detailed explanation for what you need to pay attention for when implementing SafetyNet.

iOS DeviceCheck

Until recently the device check was very limited in is usefulness, but now with iOS 14 they also the app test feature to sign the requests sent to the API server, but it still have some limitations, but I have not had the time to full explore this new feature thus I will not be able to give the same detailed explanation I gave for what to watch for when implementing the iOS device check, but I can recommend you this article:

It’s important to know that App Attest is not a “is this device jailbroken?” check, as that has been proven over and over to be impossible to perform. Instead, it aims to protect server requests in order to make it harder for hackers to create compromised versions of your app that unlock premium features or inserts features like cheats. Note the word harder: as jailbreakers have physical access to their devices, nothing will completely safeguard you from fraud in this case.

If you have a large user base, Apple recommends you to gradually roll this feature as requests to attestKey are rate limited. After carefully rolling it out for existing users, you can guarantee that it will only be called for new users.

So while this is a very good improvement from Apple it's rate limited, therefore care must be taken in what requests we decide to use it and how frequently the attestations are performed.

Mobile App Attestation

This is a concept that you can build on top of the Android SafetyNet and iOS device check solutions, and you can read my answer to the question How to secure an API REST for mobile app? in order to understand more about how the Mobile App Attestation concept works. You want to read about it in the section "A Possible Better Solution".

Do you want to go Going 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.

Exadra37
  • 11,244
  • 3
  • 43
  • 57