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.