Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to secure app - backend communications?

I have one iOS app and also a small backend that I use so far to manage the apns (Apple Push Notifications). The registration process is just a GET call with parameters to my backend, and since there is no 'authentication' or any other kind of control, I fear that anybody could just overload my backend with fake devices registering.

So the main question is: how could I make this kind of app-sending-info-to-backend transmissions secure when there is no authentication?

One simple idea that comes to my mind is generating some kind of HASH using the token that the app must supply when registering the device...

like image 664
apascual Avatar asked Dec 20 '22 18:12

apascual


1 Answers

There is no way to completely solve this problem. It is not possible to know that it is your app that is connecting. All you can do is add a little obfuscation.

Your best first step is to use SSL with a pinned certificate to make Man-in-the-Middle attacks harder. Client-side certs can help, but are a bit of a pain to set up and aren't going to buy you a lot over other solutions.

If you have a pinned certificate and SSL, just sending a shared secret along with the GET is probably as good as you need. Change the secret from release to release so you can age out old ones. If someone has reverse-engineered your app enough to beat the pinned certificate (or to read the shared secret directly), then they're going to break all the rest of these approaches, too.

Even so, here are some more that add a little extra layer:

Bidirectional shared-secret verification with AES is a good and simple approach, but requires a handshake (i.e. you can't do it with a single GET). You can of course just implement this one-way (so the server verifies the key, but not the client), but you still need a handshake.

If you want to keep your auth token to a single GET and can't pin your SSL certificate, and you can make your GETs idempotent (which good REST calls should be anyway), then this is a simple implementation:

  • Construct GET request
  • Calculate HMAC(SHA-256, shared-secret, get-request, 16 bytes)
  • Send HMAC along with GET request

On iOS, this would look something like:

NSData *key = ...random 32 bytes shared with server...;
NSURLRequest *request = ...;

// Allocate some memory for the HMAC
NSMutableData *hmac = [NSMutableData dataWithCapacity:CC_SHA256_DIGEST_LENGTH];

// Convert your URL into data. This assumes that this is a GET request, so the URL
// has everything. This also assumes that the GET is idempotent, so if someone
// replays this GET request, you don't care.
NSData *requestData = [[[request URL] absoluteString] dataUsingEncoding:NSUTF8StringEncoding];

// Compute the HMAC
CCHmac(kCCHmacAlgSHA256,
       [key bytes],
       [key length],
       [requestData bytes],
       [requestData length],
       [hmac mutableBytes]);

// Truncate the HMAC (this is common practice. It's slightly better, and at least no
// worse, to send half the HMAC rather than the whole HMAC).
NSData *token = [hmac subdataWithRange:NSMakeRange(0, [hmac length] / 2)];

NSURLRequest *finalRequest = ... add the token to your request ...

You would of course compute the same thing on the server side. You can think of this as "signing the GET." If your requests are not idempotent, you really should be working on fixing that anyway. If you can't fix it, you can integrate a timestamp into the hash and throw away requests that are too old or you've seen before. (In doing this, you've made your GET idempotent....)

When you upgrade your app, you should probably change your shared secret. That way you can eventually age out old shared secrets that have been discovered.

Yes, these can all be reverse engineered. Anything that tries to authenticate the app (rather than the user) can be reverse engineered. So keep it simple, and focus more on how you would recover if it did happen.

And if at all possible, add user authentication. It's much more powerful.

like image 175
Rob Napier Avatar answered Jan 08 '23 14:01

Rob Napier