Are there any recommended strategies for securing unauthenticated sockets?

I am working on an application that has a mobile app connecting to a Phoenix backend over sockets. Part of the app is available to users without authentication. So my socket is open, the connect function always returns {:ok, socket}. I want to ensure that only my app is able to connect to the socket and prevent abuse.

A naive solution could be using an API key hard coded into the app, which can be checked at the time of socket connection. A more round about way could be to use the API key to generate a Phoenix token via an HTTP end point, and use that token for socket authentication. The obvious problem here is the API key can be compromised, but apart from that, is there a security vulnerability here? Are there any better ways of achieving this?

Thanks

If it’s ios you might be able to create an icloud object from ios and check it from your webserver to validate an ios user. I don’t know what could be done on android. Hardcoding any api key into the app can most of the time be restored.

An easier approach would probably be rate-limiting your public socket endpoint by ip address.

Some Context

Just to give a little context I work as a Developer Advocate for API security in mobile apps and I reply often to this type of security questions in Stackoverflow. You can see here all my replies in the security tag and you will find a lot of questions were developers are trying to more or less achieve the same as you.

One of the replies that maybe will interest you more will be this one:

The Difference Between Who vs What in the API Request

What you are looking to achieve is very hard to do so, but not impossible. For any developer to understand why is so hard they need to first understand the difference between who is in the API requests versus what is doing the API request and more often then not I realise that developers have a misconception on this regard. To clarify this difference I always recommend to read a section of this article I wrote, where I discuss it in more detail, but the main take way is:

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.

Reverse Engineering

API keys are very easy to extract from mobile apps via reverse engineer techniques, like static binary analysis, MitM attacks or by using instrumentation frameworks that hook at runtime into your code to manipulate it and/or extract data.

I have written some articles that exemplify the use of such techniques:

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.

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.

Today I will show how to use the Frida instrumentation framework to hook into the mobile app at runtime and instrument the code in order to perform a successful MitM attack even when the mobile app has implemented certificate pinning.

Frida is one of the most popular instrumentation frameworks and is very powerful:

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.

Possible Solutions

Bear in mind that you first need to secure the API request that establishes the socket connection. So, you need to be sure that this request comes indeed from a genuine and untampered version of your mobile app.

To start with you should implement certificate pinning in your mobile app and I still strongly recommend it despite I have shown how to bypass it.

You can use the Mobile Certificate Pinning Generator to auto generate for your the pinning configurations for Android and iOS:

Next you can rely on the Phoenix token to authenticate each socket event but you need to always bear in mind that an attacker using Frida can always circumvent it, therefore you will need to equip your mobile app with a way to detect instrumentations frameworks and let the backend know that the mobile app cannot be trusted. The usual approach here is to use in the mobile app a RASP solution:

Runtime application self-protection (RASP) is a security technology that uses runtime instrumentation to detect and block computer attacks by taking advantage of information from inside the running software.

RASP technology is said to improve the security of software by monitoring its inputs, and blocking those that could allow attacks, while protecting the runtime environment from unwanted changes and tampering.

The issue with this solutions is that they work on the client side and the API backend doesn’t have visibility into it, therefore will never know if the mobile app is compromised or not, plus the RASP solutions makes the decision in the client side therefore also subjected to be manipulated by the attacker when is able to start an instrumentation framework without being detected.

To tackle the shortcoming of in-app security decisions it’s necessary to delegate them to a backend that sends challenges to be executed in the mobile app and based on the response it detects if the mobile app can be trusted or not and this is what you can call a Mobile App Attestation solution as I explain in the Stackoverflow reply. As far I am aware you don’t have any open source solution to implement it, only a SaaS solution(I work here). Recently iOS have released also their version of a Mobile App Attestation service that you can try to explore and use.

The bottom line here is that you need to apply security in depth with several layers of defence and how many you want or need to add will depend on your budget, resources and what is required by law and standards in your area.

Let me know if you have any doubts and feel free to ask any question.

11 Likes

Wow thank you for this amazingly detailed answer! It has given me much to read about and learn. I never realized that it was such a difficult problem. I suppose we will go about adding security incrementally as and when the budget allows. Many thanks again!

1 Like

You and many others on our industry and until 3 years ago I was one of them.