Protect my Expressjs app routes from requests outside my android app - android

I have a full application API written in node.js with Express.. Now, the API should be only accessed from my Android application, how can I protect the node app from outside requests?
If I use some kind of a password protection, I'll have to write that password in my android app and since the application is available to everyone, the password can be easily found.. What is the solution to this kind of situations?

Web based security can be a bit tricky sometimes, but if you have an app you could use a token-base approach.
When your application starts, it can request a token from your API, which then must be present in all other requests to your API.
Did a quick search for this kind of thing and came upon this page, which might be worth a look: http://thejackalofjavascript.com/architecting-a-restful-node-js-app/

Related

Google Authenticator - User Registration withOUT Mobile App

We are developing Native Mobile Application : Android platform, Ios Platform (Swift).
Instead of asking user to download and install https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2&hl=en_IN mobile app and then generate a QR code in our application to be scanned by this app, we are willing to do it api way. Means We want to call Google Authenticator API pass it QR image, secret and user is registered
Is this Ok and possible. Any one using it please suggest.
I'm not going to say that this is impossible, but integrating Google Authenticator would be a nightmare, and likely wouldn't do what you're expecting it to do. Allow me to explain.
Problem #1
For each instance of the app, you'll have to have a Unique Identifier to pair it to Google's Authenticator. In other words, you'll need to generate a new QR code for each device, pass that off to the system (Which doesn't exist without the app.) to pair the application. This is going to require a "Log-In" to properly store.
Check out this for a possible work-around to Problem #1: https://authenticatorapi.com/
Problem #2
If you're already logging in and the device is already being authenticated, what purpose does the Google Authenticator provide? Well, I'm assuming it allows you to prevent unauthorized access, possibly prevent more than one device. There are infinitely easier ways to manage this, location services are the first one that comes to mind for me.
Possible Solution (iOS)
This is absolutely my go-to method for handling authentication. Encourage or require your users to use 2FA (Two Factor Authentication) attached to SMS messaging. A simple line of code such as this will grab an SMS one-time code.
// Available as of iOS 12, make sure to check version.
self.verifyCodeTextField.textContentType = .oneTimeCode
Android SMS Retrieval
Android Auto-SMS-Retrieval https://developers.google.com/identity/sms-retriever/overview
I don't know it all, most certainly, but I hope this opens the floor for some discussion and brings forth a solution or explanation to your question.
Research Material
Google Authenticator available as a public service?
java API for google Authenticator

Restrict API requests to only my own mobile app

Is there any way to restrict post requests to my REST API only to requests coming from my own mobile app binary? This app will be distributed on Google Play and the Apple App Store so it should be implied that someone will have access to its binary and try to reverse engineer it.
I was thinking something involving the app signatures, since every published app must be signed somehow, but I can't figure out how to do it in a secure way. Maybe a combination of getting the app signature, plus time-based hashes, plus app-generated key pairs and the good old security though obscurity?
I'm looking for something as fail proof as possible. The reason why is because I need to deliver data to the app based on data gathered by the phone sensors, and if people can pose as my own app and send data to my api that wasn't processed by my own algorithms, it defeats its purpose.
I'm open to any effective solution, no matter how complicated. Tin foil hat solutions are greatly appreciated.
Any credentials that are stored in the app can be exposed by the user. In the case of Android, they can completely decompile your app and easily retrieve them.
If the connection to the server does not utilize SSL, they can be easily sniffed off the network.
Seriously, anybody who wants the credentials will get them, so don't worry about concealing them. In essence, you have a public API.
There are some pitfalls and it takes extra time to manage a public API.
Many public APIs still track by IP address and implement tarpits to simply slow down requests from any IP address that seems to be abusing the system. This way, legitimate users from the same IP address can still carry on, albeit slower.
You have to be willing to shut off an IP address or IP address range despite the fact that you may be blocking innocent and upstanding users at the same time as the abusers. If your application is free, it may give you more freedom since there is no expected level of service and no contract, but you may want to guard yourself with a legal agreement.
In general, if your service is popular enough that someone wants to attack it, that's usually a good sign, so don't worry about it too much early on, but do stay ahead of it. You don't want the reason for your app's failure to be because users got tired of waiting on a slow server.
Your other option is to have the users register, so you can block by credentials rather than IP address when you spot abuse.
Yes, It's public
This app will be distributed on Google Play and the Apple App Store so it should be implied that someone will have access to its binary and try to reverse engineer it.
From the moment its on the stores it's public, therefore anything sensitive on the app binary must be considered as potentially compromised.
The Difference Between WHO and WHAT is Accessing the API Server
Before I dive into your problem I would like to first clear a misconception about who and what is accessing an 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 if you are not using user authentication in the app, then you are left with trying to attest what is doing the request.
Mobile Apps should be as much dumb as possible
The reason why is because I need to deliver data to the app based on data gathered by the phone sensors, and if people can pose as my own app and send data to my api that wasn't processed by my own algorithms, it defeats its purpose.
It sounds to me that you are saying that you have algorithms running on the phone to process data from the device sensors and then send them to the API server. If so then you should reconsider this approach and instead just collect the sensor values and send them to the API server and have it running the algorithm.
As I said anything inside your app binary is public, because as yourself said, it can be reverse engineered:
should be implied that someone will have access to its binary and try to reverse engineer it.
Keeping the algorithms in the backend will allow you to not reveal your business logic, and at same time you may reject requests with sensor readings that do not make sense(if is possible to do). This also brings you the benefit of not having to release a new version of the app each time you tweak the algorithm or fix a bug in it.
Runtime attacks
I was thinking something involving the app signatures, since every published app must be signed somehow, but I can't figure out how to do it in a secure way.
Anything you do at runtime to protect the request you are about to send to your API can be reverse engineered with tools 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.
Your Suggested Solutions
Security is all about layers of defense, thus you should add as many as you can afford and required by law(e.g GDPR in Europe), therefore any of your purposed solutions are one more layer the attacker needs to bypass, and depending on is skill-set and time is willing to spent on your mobile app it may prevent them to go any further, but in the end all of them can be bypassed.
Maybe a combination of getting the app signature, plus time-based hashes, plus app-generated key pairs and the good old security though obscurity?
Even when you use key pairs stored in the hardware trusted execution environment, all an attacker needs to do is to use an instrumentation framework to hook in the function of your code that uses the keys in order to extract or manipulate the parameters and return values of the function.
Android Hardware-backed Keystore
The availability of a trusted execution environment in a system on a chip (SoC) offers an opportunity for Android devices to provide hardware-backed, strong security services to the Android OS, to platform services, and even to third-party apps.
While it can be defeated I still recommend you to use it, because not all hackers have the skill set or are willing to spend the time on it, and I would recommend you to read this series of articles about Mobile API Security Techniques to learn about some complementary/similar techniques to the ones you described. This articles will teach you how API Keys, User Access Tokens, HMAC and TLS Pinning can be used to protect the API and how they can be bypassed.
Possible Better Solutions
Nowadays I see developers using Android SafetyNet to attest what is doing the request to the API server, but they fail to understand it's not intended to attest that the mobile app is what is doing the request, instead it's intended to attest the integrity of the device, and I go in more detail on my answer to the question Android equivalent of ios devicecheck. So should I use it? Yes you should, because it is one more layer of defense, that in this case tells you that your mobile app is not installed in a rooted device, unless SafetyNet has been bypassed.
Is there any way to restrict post requests to my REST API only to requests coming from my own mobile app binary?
You can allow the API server to have an high degree of confidence that is indeed accepting requests only from your genuine app binary by implementing the Mobile App Attestation concept, and I describe it in more detail on this answer I gave to the question How to secure an API REST for mobile app?, specially the sections 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.
No. You're publishing a service with a public interface and your app will presumably only communicate via this REST API. Anything that your app can send, anyone else can send also. This means that the only way to secure access would be to authenticate in some way, i.e. keep a secret. However, you are also publishing your apps. This means that any secret in your app is essentially being given out also. You can't have it both ways; you can't expect to both give out your secret and keep it secret.
Though this is an old post, I thought I should share the updates from Google in this regard.
You can actually ensure that your Android application is calling the API using the SafetyNet mobile attestation APIs. This adds a little overhead on the network calls and prevents your application from running in a rooted device.
I found nothing similar like SafetyNet for iOS. Hence in my case, I checked the device configuration first in my login API and took different measures for Android and iOS. In case of iOS, I decided to keep a shared secret key between the server and the application. As the iOS applications are a little bit difficult to reversed engineered, I think this extra key checking adds some protection.
Of course, in both cases, you need to communicate over HTTPS.
As the other answers and comments imply, you cant truly restrict API access to only your app but you can take different measures to reduce the attempts. I believe the best solution is to make requests to your API (from native code of course) with a custom header like "App-Version-Key" (this key will be decided at compile time) and make your server check for this key to decide if it should accept or reject. Also when using this method you SHOULD use HTTPS/SSL as this will reduce the risk of people seeing your key by viewing the request on the network.
Regarding Cordova/Phonegap apps, I will be creating a plugin to do the above mentioned method. I will update this comment when its complete.
there is nothing much you can do. cause when you let some one in they can call your APIs. the most you can do is as below:
since you want only and only your application (with a specific package name and signature) calls your APIs, you can get the signature key of your apk pragmatically and send is to sever in every API call and if thats ok you response to the request. (or you can have a token API that your app calls it every beginning of the app and then use that token for other APIs - though token must be invalidated after some hours of not working with)
then you need to proguard your code so no one sees what you are sending and how you encrypt them. if you do a good encrypt decompiling will be so hard to do.
even signature of apk can be mocked in some hard ways but its the best you can do.
Someone have looked at Firebase App Check ?
https://firebase.google.com/docs/app-check
Is there any way to restrict post requests to my REST API only to requests coming from my own mobile app binary?
I'm not sure if there is an absolute solution.
But, you can reduce unwanted requests.
Use an App Check:
The "Firebase App Check" can be used cross-platform (https://firebase.google.com/docs/app-check) - credit to #Xande-Rasta-Moura
iOS: https://developer.apple.com/documentation/devicecheck
Android: https://android-developers.googleblog.com/2013/01/verifying-back-end-calls-from-android.html
Use BasicAuth (for API requests)
Allow a user-agent header for mobile devices only (for API requests)
Use a robots.txt file to reduce bots
User-agent: *
Disallow: /

Protect public API (no registration required)

I have a public REST API that I want to protect. I've read about HTTP basic authentication, OAuth, APIs Key ... but as far as I know, this methods require registration (username and password). I want that the users (Android apps) of my service can use it without registration and login.
So, ideally, I want that only Android apps can use the service and I would like to control the usage of the service. I've thought about get something unique about Android devices but I think it is easily falsificable.
The reason for no registration is that the service is very simple (check out the bus arrivals, and participate sending some time arrivals) and I think is overkill that users have to provide a username/password for such a simple service.
How I can achieve this?
I want that only Android apps can use the service... How I can achieve this?
You can't.
You can try to casually reduce the number of things other than Android apps that can use your service (e.g., have your app use a custom user agent header in the HTTP requests, and use SSL). However, people who are determined to get past that will be able to do so, by reverse-engineering your app, or sniffing on the HTTP traffic.

Should Android apps with a server side component access Facebook directly?

If I am building an Android app that uses the Facebook SDK and also has a web app that has most of the same functionality, how should the Android app handle social actions? Should it directly make requests to the Facebook API through the SDK or should it post to the web app server through my own API and allow the web-app to make the request to Facebook on behalf of the Android app? Most of the Facebook for Android examples use the former approach however none explicitly discuss the best practice when there is a web backend that will have the same social functionality as the Android app.
I've been putting my mind into a similar problem before. It was a PHP app, but essentially the design choice was to either put the FB-interaction into the frontend (JS-SDK) or into the backend and proxy it (PHP-SDK). Sadly haven't found much guidance either, so I had to make up my own mind.
As so often there seems no per-se answer, it depends on what you are doing with FB and how deep it is integrated into whatever your app/webapp/backend are doing. Is your Android otherwise more a client-side app or does it rely on other features delivered by the web-app via web-service? Is it somehow integrated with users actions that are dispatched to the backend, or does it just offer some additional gimmicks (e.g. 'Like' button, anything in the lines) Are you using the SDK to authenticate and pull user related data from FB (email, name) and does that information play a role in your backend?
As I see it, it boils down to the following:
Direct communication with FB is a lot simpler to implement as you won't have an additional layer between your app and FB, i.e. proxy code, etc. So if FB is just loosely coupled it's likely the 'good-enough' option.
Patching FB from frontend to backend can get nasty - especially if you want to authenticate via FB it's kinda complex at first. However, you'll have all FB logic in a single place, shared by Android-App and Webapp, so it's obviously easier to maintain later and better to integrate with other interactions your backend might be offering.
Hope that provides some value, would be eager to see other opinions too.
Well I think both approaches are correct but the choice depends on mostly what you already have in place on the server side and if you are planing to use the same functionality from different apps like (Android,iOS, Windows Phone apps). In that case it makes sense to just get user token with permissions you require on the front end and let the web server talk to facebook using that token. You could even save this token for the user so they don't have to give permissions again if for example you have web registration and app registration. In our app we are using this approach since there are basically five front ends (Android,iOS, Desktop,Mobile Web,Full Web) this way application developers just get token using sdk on there platform (you have to use tokens and not user name, password because of facebook rules for security). On the other hand if all Facebook communication is used only inside your app and the server doesn't need to know much about it put api calls in the app.
In my opinion, it is best to use the available SDKs/APIs for each given platform instead of trying to write your own centralization and use a single library. Since you are specifically interested in how the Android app should handle social interactions, I suggest using the Facebook SDK for Android.
While it does increase the size of the code you must maintain and the SDKs/APIs you must learn as your list of platforms increases, the most important factor for this approach is the user experience. By sticking with the native libraries, and growing your app as those libraries evolve, you will be providing your users with an experience that they are most likely to be used to. They won't have to learn how to use your app, but will be able to make posts, update their status, and look at their friend list using controls that they are accustomed to using. Additionally, you will be able to take advantage of specific platform functionality (in the mobile case, such as having your app post to a users feed in a way that promotes your app: https://developers.facebook.com/docs/tutorials/androidsdk/3.0/games/feed/)

Prevent "fake-client" for ios app

We have an android and ios app which sends data and commands to a server with http webservice. How can i prevent the possibility, that fake-clients also can send something to the server? How can I determine serversidely if the data/command really comes from our apps.
You cant really prevent it. There are several techniques to make it harder for people abusing your services.
A simple check can be to check the user agent calling your webservice. Another pretty common one is to use a simple authentication via user/password authentication on your webserver. The username and password will be embedded into your app.
If you have enough time you should think about using a combination of this two methods plus authentication with a embedded ssl certificate. You simply could add this to your project and if someone really want to abuse your service, he have to extract this certificate atleast form your application.
There are some other useful techniques but you cant prevent reverse engineering or network sniffing.
Sincerely,
fuxx
The most robust solution is not to try. Techniques like DasFuxx's answer suggests can make it faintly harder, but someone can always decompile your application and get whatever secrets you have embedded in it.
Instead, follow the rule of multiplayer game development:
Don't trust the client.
Don't think about your application as the user interface. Think about your network protocol/API as being the user interface; then design that interface so that it cannot be abused.
It may not be possible to do so completely, but insofar as you succeed, you have true security (rather than fighting the same losing battle as DRM systems).
I would implement oAuth. See the following link for more information on how to implement such a solution.
You can't. It's that simple...

Categories

Resources