How can the server know that web traffic comes from the App?

I know that you can use https to verify that the server is the real server.

How can the server know that web traffic comes from the App ?

I mean, you could create a bot that keeps connecting to the server and consume all its CPU time, and that is what we want to avoid.

We want that the server only serve requests that come from the app.

How can that be done with ionic ?

It cannot.

That said, you could do a pretty good job hindering casual abuse:

  • check the user agent (easily spoofed)
  • use secret/undocumented API’s (security by obscurity)
  • use a secret key (which must be bundled with the app and is therefore vulnerable)
  • rate-limit requests (why not?)
  • etc

Good luck :smile:

About the idea of using a secret key, how would that work? like this?

  1. The app send a request to the server using https including the secret key. Because it uses https then it is encrypted and “Man in the Middle” attack cannot occur.
  2. The server then verifies that the secret key is correct.

You say : “(which must be bundled with the app and is therefore vulnerable)”, but I would ask:

  1. I think it is not vulnerable in iOS, am I right ?
  2. If I use obfuscation in Android, could that be enough to limit its vulnerability ?

Thank you for your response. :smile:

Consider: if you could protect your secrets perfectly, how would the machine read them to use them? And in your case, it probably wouldn’t matter which release (iOS or Android) got reverse-engineered; in either case, people would get to abuse your servers. So you’d do what you could, with the understanding that it’s not really fool-proof. Obfuscation is actually good for both platforms. I wouldn’t do anything that unnecessarily degrades the user experience, but of course this depends on your business situation.

Your secret key scheme sounds good. You could use the secret key to encrypt all traffic. You could use the secret key to request a session key. You could even use SSL for both client and server authentication.

Do your users have accounts? If so, you could limit each account. Otherwise, you could limit by IP address, but of course users behind NAT devices would have to share their resource pools.

Is it possible to reverse engineer iOS apps ? If so, how ?

Yes, I would agree that “You could even use SSL for both client and server authentication” is the strongest option but I guess it’s the most difficult to do with ionic, I guess.

I guess the easier way to do it with ionic is “You could use the secret key to request a session key”, do you agree with that ? (by “easier” I mean: less code to write).

I think that the way to do it would be this:

  1. Through https the app requests a (random) number from the server.
  2. That number is then transformed using the secret key in the app into a different number (number 2) using some algorithm.
  3. Through https that number 2 is sent to the server in every subsequent request of this session.

I think this is very easy to code, do you agree ?

I think you could unzip an ipa (the same way you’d unzip an apk) to examine its contents.

It’s probably easiest to just send the key itself along with every request, unless you actually need to keep state for each session.

But how do you get the ipa in the first place ? Because they are transmitted encrypted to the iPhone/iPad.

Let’s suppose somehow some user is able to get the ipa and unzip it. But the code is compiled so I guess the it is not easy to decompile. So I guess, the important thing is that the key is not written in plain text but transformed and then before the key is sent to the server it is passed through some algorithm to get the real key. Also I guess that all the ionic code in the app will reside as plain text. So that algorithm that gets the real key will need to be developed as a plugin (cordova plugin). Do you think this line of reasoning is correct ?

Yes, you are right, that is easiest.

Take a look at JSON web tokens.
This was on Hacker News yesterday.

1 Like

You can use json web tokens as a key or to replace cookies to save a login session id. I have used them for both on different projects. However keep in mind anyone with access to your app can hook their phone up to charles or something similar and see all your api traffic unencrypted. That is unless you do javascript encryption and https which would still just require them to look into your apk or ipa. Either way your only setting the bar higher for who will be able to reverse engineer your api.

Accounts help alot with this problem because you can ban devices and users along with apis if you find them to be abusive.

@osjs is really concerned about server resources being abused, and there are ways to address that. For example, you can rate limit requests by IP address. Server load is really an issue to be fixed by your service, because even if you have traffic only coming from the app do you have the infrastructure to scale up if it becomes popular?

As far as limiting access, I agree with @epelc that accounts help solve this problem. Setting a private key, token, or something that is contained in the app code could be discovered by someone who could dissect the app. With an account, you can grant a unique token to each app and selectively disable an account when you notice something is going wrong.

Ultimately, I would first worry about the scalability of your server, then if still necessary add accounts to be able to provide unique tokens for each app.

But can they ?

Using Cordava, ionic works inside a web view, so how is the https validated ? Using the digital certificates stored in the phone ? After reading about “SSL Proxying” in charles it could seem plausible to just install the charles certificate in the phone and unencrypt https.

But can the digital certificate of the server be stored inside the app and being compared to see if the server is the real server ?

(Comment: When I read about charles, I said “wow!, https is not too secure for apps”, I wonder if banking apps take precautions about that).

Yes, that looks like a good idea.

I have this idea, maybe you could give me feedback if it is a good idea or not:

To simplify the system, better to just use (unsecure) http and send everything with JSON Web tokens with encryption where the key is always the same and is stored inside the app (but not as plain text). So if an attacker wants to hack the app, he or she will need to open the ipa or apk and decompile the code. It could probably take too much time for someone with those skills to be worth the effort.

Don’t over complicate things… The app is just like any other browser out there. Handle the platform as such.

Think of security in the app, as you do in the regular browser. Don’t trust anything that gets submitted to your server, always perform the correct validation and sanitation before using the data on the server.

All you really need is to include a custom header that tells your server that the request is originating from your app.
The header shouldn’t be used for anything critical.

anti-flood, HIPS, WIPS, WAF etc shouldn’t be handled by your application in any case. Leave that to professional software, like ASL.

They’re also transmitted encrypted to your iTunes library… and stored unencrypted on disk. Of course, if you had a jailbroken iDevice, you could examine its filesystem directly as root.

What do you mean when you say that the code is compiled? The original html/css/js should be recoverable. You could do a lot of stuff to obfuscate the code or key, and you’d hinder a lot of casual abusers. Ultimately, any such defense would fall to a targeted attack. I’d balance the costs and benefits.

I’d agree with @Evanion. The “custom header” could even be the user agent :wink: