I would like to know if my Firebase Backend (Firestore and Cloud Functions) are safe by using App Check if my Flutter App (iOS/Android) is reverse engineered.
I imagine the App Check is client based. If the client is reverse engineered, then the backend wouldn't know if it's "my" client or the "bad" client which was reverse engineered?
App Check works with so-called attestation providers on each supported platform to attest that API calls come from your genuine code on a genuine device. These providers are at this point quite well vetted on both iOS and Android, and are getting better on Web.
For example, without App Check a malicious user can extract the Firebase configuration from the released app, and then for example call the Firestore APIs with those configuration details. You'd then use security rules to protect against the attack.
When you use App Check, their API calls won't be attested, so they will be rejected by Firebase before they even reach Firestore and your security rules. So with one sweep, you've ruled out a lot of abuse on that attack vector.
But there is still a potential for abuse, even when you use App Check. That's why you should always combine App Check with other security measures, such as the server-side security rules that exist for Firestore (since you tagged with that) and other Firebase products.
I recommend also checking out:
How strong is the security provided by App Check?
Is it safe to expose Firebase apiKey to the public?
Related
We have a live mobile application supporting registering with the user's mobile number.
We send OTP upon each register request and now we have hundreds of spam requests costing a lot of money due to the SMS service fee.
Rate limiting on Ip is applied.
Rate limiting on device id is also applied.
The register request is secured by adding a signature to the header using the HMAC SHA-256 algorithm, the key used to generate the signature stored in mobile code.
But it turns out that this is not enough to secure the process.
Is there any other practice we should do to solve the spam issue?
We are using Flutter for the mobile app
Your Problem
We have a live mobile application supporting registering with the user's mobile number. We send OTP upon each register request and now we have hundreds of spam requests costing a lot of money due to the SMS service fee.
Registering with the mobile phone number to deter spam isn't enough because a lot of services exist in the internet to provide anyone with free mobile phone numbers, that are often used to workaround registrations or any other services that require you to provide a number.
Rate limiting on Ip is applied.
Malicious users can rotate their IP address when they use a script (bot) or run your app in an emulator. Also IP addresses in mobile are very dynamic, its not like in residential broadband where they stay stable for long periods.
Rate limiting on device id is also applied.
The malicious user will rotate the device id when using a bot, an emulator or a rooted device.
Reverse Engineering
The register request is secured by adding a signature to the header using the HMAC SHA-256 algorithm, the key used to generate the signature stored in mobile code.
The malicious user will reverse engineer you mobile app statically to see how the HMAC signature is done and then replicate it on its script. In a series of articles around Mobile API Security I wrote an article about statically reverse engineering an app, while in the context of extracting an API Key the principles remain to extract the logic for the HMAC signature. You can learn how to it by yourself on your own app by applying the same basic technics I used on 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.
During this article we will use the Android Hide Secrets research repository that is a dummy mobile app with API keys hidden using several different techniques.
The malicious user may also reverse engineer dynamically your app to understand how it communicates with your API server in order to do exactly the same on its bot.
This is usually done with a MitM attack on a device that the malicious user controls and a lot of open-source tools exist to help with the task, being the most known ones mitmproxy and Frida. Turns out that I also wrote an article on how to use this tools, not to extract the HMAC signature, but to bypass certificate pinning, but the basic mechanics to perform the dynamic analysis are the same, therefore I invite you to try this techniques against your own app. Learn the basics of MitM attack with Frida and mitmproxy on the article Bypassing Certificate Pinning:
In this article you will learn how to repackage a mobile app in order to disable certificate pinning and in the process you will also learn how to create an Android emulator with a writable system to allow for adding the custom certificate authority for the proxy server into the Android operating system trust store. This will allow us to bypass certificate pinning and intercept the requests between the mobile and its backend with a MitM attack.
The Difference Between WHO and WHAT is Accessing the API Server
But it turns out that this is not enough to secure the process.
No, its not enough because its not that hard to bypass with the several techniques I shown above.
In order for you to improve your security posture when developing an application you first need to understand the difference between who and what is doing the request to the API server.
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.
When you grasp this idea and it's ingrained in your mindset, then you will look into mobile API security with another perspective and be able to see attack surfaces that you never though they existed before.
Possible Solutions
Security must be always seen as a layered approach, where you add as many layers as needed to deter the opponent from even trying to break them, or if in the case they try they will need a lot of resources, knowledge and time. This not new to software development, its being done for centuries, like in the medieval castles and prisons.
Is there any other practice we should do to solve the spam issue?
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.
From this answer the Mobile App Attestation would be the most suitable for you to employ in order to give a very high degree of confidence to your API backend that the request is indeed from what it expects, a genuine and unmodified version of your mobile app, not from a bot, an emulator, a jail broken device or whatever other technique being used by the malicious user.
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.
I am building a mobile app and I was wondering if my API key can be seen when I make a GET request to my database through the API?
What I am currently doing is making an HTTP GET request where one of the params is the API Key. So if any user were to see this URL, they also can fetch this data.
Can any user see this URL being sent? I am doing this through the Flutter HTTP package.
Sensitive Data in URLs
What I am currently doing is making an HTTP GET request where one of the params is the API Key. So if any user were to see this URL, they also can fetch this data.
Using sensitive data, like API Keys, as an URL query parameter was made popular by many popular internet services since earlier days, thus a lot of tutorials and docs use this approach and this is a huge disservice for the security of any application, but a huge gain in terms of developer convenience.
Keeping sensitive data in an URL query parameter is a security disaster waiting to happen at any moment, but it's the type of disaster that happens and you don't notice until is too late, like when you discover you have been data-breached because an attacker was able to get the API Key from the logs server that was left open to the public or because you use a CI/CD pipeline that logs them by design (yes a famous one does that).
The correct place for an API key is as an header in the request, not as a URL parameter or a post parameter, but can still end-up in your logs server, but is less likely.
Extracting an API Key with a MitM Attack
I am building a mobile app and I was wondering if my API key can be seen when I make a GET request to my database through the API?
Yes, it can be seen and extracted from your mobile app binary or by intercepting the API requests made through HTTPS, also known as a Man in the Middle (MitM) attack.
Can any user see this URL being sent? I am doing this through the Flutter HTTP package.
To see how this can be easily achieved with MitM attack I invite you to read the article Steal that Api Key with a Man in the Middle Attack:
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.
If you want to learn more about API and Mobile security then 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.
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.
Yes if you are not using ssl you are sending everything in plain text which can be intercepted.
if you are using ssl still your URL can be stored in logs on api server so instead of sending key in query parameter use POST request and append the key in custom header or form parameters.
I'm building an application where I need to make a request in the client-side frontend app to an external API, and I'm at a bit of a loss for how to make this maximally secure so that only valid requests can be forwarded to this external API and not whatever anyone wants.
As a first step in security, I've made it so that the client-side app can't speak to the external API directly, but must instead hit our own server-side API, which then proxies the request to the external API, so that the credentials for hitting the external API are at least stored solely server side and not client side.
This, however, has led to the same fundamental issue - how do I secure whatever credential/authentication system I use to authenticate requests I make from the client-side app to our own server-side app?
The issue is this is an online restaurant ordering service, and so we don't expect users to authenticate themselves with say, usernames and passwords before being able to place orders necessarily, and so order placement, which triggers the external API call, isn't gated behind any username/password scheme, and must be available to all consumers of the frontend app.
What's the best practice for security here? I've enabled CORS whitelisting as a minimum practice, such that only requests from our own domain are theoretically allowed by our server side API endpoint, but CORS is trivially bypassed if someone chooses to just spoof the origin URL.
What other options are available? I'm sure I must just be missing something trivial, since this must be an extraordinarily common issue with an established best practice, but I'm just somehow failing to find it.
Thank you!
As a Developer Advocate for API and Mobile security, seeing a developer that really cares about their app security always makes me smile, especially when they already show some effort was made to secure it, therefore accept my congratulations for your efforts.
My Answer Context
I'm building an application where I need to make a request in the client-side frontend app to an external API, and I'm at a bit of a loss for how to make this maximally secure so that only valid requests can be forwarded to this external API and not whatever anyone wants.
So, you have not detailed if it's a web app or a mobile app, and once my expertise relies on mobile and API security I will be answering with the assumption that is a mobile app.
The Challenge
The issue is this is an online restaurant ordering service, and so we don't expect users to authenticate themselves with say, usernames and passwords before being able to place orders necessarily, and so order placement, which triggers the external API call, isn't gated behind any username/password scheme, and must be available to all consumers of the frontend app.
You have here a complicated challenge to solve, because you have an app that is open to the public, no user authentication/identification of any sort, but that requires rules of access to the underline resources as if it was behind user authentication and authorization, but even if it was, it would still be vulnerable to being abused.
To understand why I need to clear a misconception that usually I find among developers of any seniority, that is about the difference between who and what is accessing an API server.
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.
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.
So, in your case you cannot identify who is in the request, thus you need a solution that is able to give a very high degree of confidence to the API backend that the request is indeed from what it expects, a genuine and unmodified instance of your app.
Possible Solutions
I'm building an application where I need to make a request in the client-side frontend app to an external API, and I'm at a bit of a loss for how to make this maximally secure so that only valid requests can be forwarded to this external API and not whatever anyone wants.
This requires very advanced solutions to properly secure, thus isn't at all trivial to achieve as you may think:
I'm sure I must just be missing something trivial, since this must be an extraordinarily common issue with an established best practice, but I'm just somehow failing to find it.
And yes, it's a common issue that often is neglected or not addressed properly, and the first step to solve it is to have a clear picture about the difference between who vs what is in a request, otherwise the devised solutions will fail to address the issue properly.
For Mobile Apps
Here I recommend you to go through 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.
This answer will show you several solutions, like WAFs and UBAs, but ends with a recommendation to use a Mobile App Attestation concept.
In a nutshell the Mobile App Attestation will allow the API backend to have a very high degree of confidence that the request is indeed from what it expects, a genuine and modified instance of the mobile app.
For Web Apps
You can learn some useful techniques to help your API backend to try to respond only to requests coming from what you expect, your genuine web app, and to do so I invite you to read my answer to the question Secure api data from calls out of the app, especially the section dedicated to Defending the API Server.
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.
For Web Apps
The Web Security Testing Guide:
The OWASP Web Security Testing Guide includes a "best practice" penetration testing framework which users can implement in their own organizations and a "low level" penetration testing guide that describes techniques for testing most common web application and web service security issues.
Ultimately your client needs to perform some operation on 3rd party API.
So we know that some operations should be allowed, and based on your description we also know that not every operation should be allowed.
So your security should be based on this premise. Don't create a dumb proxy that forwards every single request, but your intermediate API should only specifically allow the operations that you want it to allow, based on the rules you set.
If you don't have a username & password, you probably still have some other kind of rule that identifies a person (email/phone number?), which means you can create an authentication system.
Or maybe your 3rd party service should only be called after a user completed an order with a credit card, that logic needs to exist on your API.
TL;DL
Is it OK to store api key for Google map api on Firebase Firestore with security rules ?
Question
I'm working on map features using google_maps_flutter plugin. This package describes to store the key on source code on its document, but this seems to be insecure.
Many developers describing that the most secure way to manage api key is to store on server side and I agree with this idea.
I found the issue but it seems that the plugin does not have a way to provide the api key dynamically.
In the iOS sdk, they have GMSServices.provideAPIKey(Could not find same kind of methods on Android) and this allows to provide api key dynamically.
If the plugin support these features in future, is it OK to store the key on firestore with security rules?
Thank you
If your third-Party API Key are sensitive, they should stay on the server and never reach the User's device.
So, you could store them on Firestore with strong security rules (i.e. only readable with admin privileges) and then place the third-party API calls within Firebase Cloud Functions.
I have actually one SPA in ReactJs + one mobile application in Flutter + one REST API developed with SailsJs running on a separate server. I managed user authentication with a secured session cookie sent back by the API when we are login with valid information (id/password).
So all the endpoints that require users to be authenticated are protected (unless there are others security best practices that I'm not aware of?). The session cookie expiration and validity are checked with each call to one of the protected endpoints.
I really read a massive amount of topics and blog posts talking about securing REST API. And my problem is never or barely represented. So now my main problem is :
How can I restrict my public API endpoints (login & register currently) that does not require users to be authenticated (since there are the endpoints used to achieve this mission...) to be used only in my trusted client apps (web and mobile)?
How can I prevent another app developed by another person to use these endpoints?
I don't want anyone to login via my API unless it is done in the client apps I am developing... I don't want anyone to replicate my applications and successfully use my API that way with 0 protection, without knowing it...
I see a lot of popular services with login API routes (Heroku for example) that can't be accessed in Postman with the same parameters (403 error code). So it is possible. But how they do that? There is nothing in specialized forums that handle this or I missed something!
I tough of a secret token stored in the client to authenticate it but it is literally public with web developer tools for example.
Need some advice.
Thanks
USER AUTHENTICATION IS NOT APP AUTHENTICATION
So all the endpoints that require users to be authenticated are protected...
This endpoints are only protected regarding to identify, authenticate and authorize Who his in the request, but not for What is doing the request, and this is a topic not very well understood among developers, be them juniors or seniors.
The Difference Between WHO and WHAT is Accessing the API Server
In an article I wrote, entitled Why Does Your Mobile App Need An Api Key? you can read with more detail the difference between Who and What is accessing your API server, from where I quote the following:
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 the Who is the user of your API server that you will be able to Authenticate and Authorize access to the data, and the What is the software making that request in behalf of the user, your genuine app, a tampered one, an automated script or someone manually poking around with your API via cURL, Postman or similar tools.
By now I hope that you have enough knowledge to understand why user(who) authentication is not the same as app(what) authentication.
LOCK THE API SERVER TO THE APPS
How can I restrict my public API endpoints (login & register currently) that does not require users to be authenticated (since there are the endpoints used to achieve this mission...) to be used only in my trusted client apps (web and mobile)?
I think that by now it may be clear to you that it's not only the login and registration endpoints that need to be protected from What is doing the request.
How can I prevent another app developed by another person to use these endpoints?
I don't want anyone to login via my API unless it is done in the client apps I am developing... I don't want anyone to replicate my applications and successfully use my API that way with 0 protection, without knowing it...
This is extremely hard to achieve for web apps, but possible with an high degree of confidence for mobile apps when the Mobile App Attestation concept is implemented.
For web apps
Due to the nature of how the web was built, all it's necessary to inspect a web app is to hit F12 or inspect the page source, and then search for whatever you need to access the API server from another tool.
You can learn some useful techniques to help your API server to try to respond only to requests coming from What you expect, your genuine web app, and to do so I invite you to read my answer to the question Secure api data from calls out of the app, specially the section dedicated to Defending the API Server.
For mobile apps
To learn how you can lock your API server to your mobile app I recommend you to read my answer to
the question How to secure an API REST for mobile app? for the sections on Securing the API Server and A Possible Better Solution.
Endpoints to Secure
So all the endpoints that require users to be authenticated are protected (unless there are others security best practices that I'm not aware of?).
It's up to you if you only want to enhance the security of your login and register endpoints, but my advice is that you enhance the security of all them regarding the detection for What is accessing them.
POSTMAN WITH HEROKU AND OTHERS
I see a lot of popular services with login API routes (Heroku for example) that can't be accessed in Postman with the same parameters (403 error code). So it is possible. But how they do that? There is nothing in specialized forums that handle this or I missed something!
I never used Heroku, but when I am using an API that doesn't work in Postman, but works in other clients, let's say from cURL, then I disable Postman from sending it's own user-agent and normally the API will start accepting the requests.
If doesn't then they may be doing device fingerprinting:
A device fingerprint or machine fingerprint is information collected about the software and hardware of a remote computing device for the purpose of identification. The information is usually assimilated into a brief identifier using a fingerprinting algorithm. A browser fingerprint is information collected specifically by interaction with the web browser of the device.
The fingerprinting can be done in active or passive mode. In active mode some Javascript runs on the client to collect some data to send back to the API server, while in passive mode it uses the information available from the request in the server, like the http headers and request parameters.
While this raises the bar to fake What is doing the request, it can be bypassed by observing how a trusted client sends the request and mimic it. For an attacker it's just a little more work to enumerate all variants and then automate them.
DO YOU WANT TO GO THE EXTRA MILE?
I really read a massive amount of topics and blog posts talking about securing REST API.
First and foremost my congratulations for putting such effort in educating yourself about securing your API.
I don't know if you already read some of the OWASP resources I am about to link, but in any response to a security question I always like to reference the excellent work from the OWASP foundation ;)
For Web Apps
OWASP Web Top 10 Risks
The OWASP Top 10 is a powerful awareness document for web application security. It represents a broad consensus about the most critical security risks to web applications. Project members include a variety of security experts from around the world who have shared their expertise to produce this list.
The Web Security Testing Guide:
The OWASP Web Security Testing Guide includes a "best practice" penetration testing framework which users can implement in their own organizations and a "low level" penetration testing guide that describes techniques for testing most common web application and web service security issues.
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.
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.