1

One of our customers had a pen test performed on our application this week and let's just say it didn't go well.

The main issue they have is that user authentication takes place on the client, rather than the server. The reason being that an attacker could decompile our (C#) application and build a modified version which could allow any password to be accepted.

The problem is, a requirement from our customer is that the application needs to work offline, so some sort of authentication will need to be done by the application without communicating with the server.

The pen testers suggested using a token system where the user authenticates with the server and it stores a token in the local database which would be used while offline, but I don't see how this solves the decompiling issue. Surely this could be bypassed in the same way?

Is my only option to tell the customer that if they want the application to be secure, then it can't work offline?

-- additional details

There isn't an "offline-mode" as such, just when an Internet connection is not available (several of the users might take a laptop to farms, for example), so authenticating with a server isn't possible. Admittedly, this isn't as much of an issue as it used to be, with 4G/5G availability.

On first login, after the initial authentication with the server, settings/config data is downloaded and stored in a local database (MSSQL or SQLite). Logging in while offline would allow access this data (so the program can function) and data the user has entered/saved.

The program has to "phone home" occasionally already (the settings expire after a week of no contact with the server), but I can't see how to stop a user from logging into the program if it is decompiled. If it downloads a token from the server, checking this could be bypassed in the same way entering a password could be.

I guess this question boils down to "is it possible to prevent an attacker decompiling my program to circumvent authentication without requiring a server?". So far the only option seems to be to use the user's password as a key to encrypt the data, but then if (when!) the user forgets their password, the data is lost.

7
  • 5
    What resources are protected by the local authentication? Only access to the server resources? Or some local data that is available anyway in plaintext on the local file system? A local password is largely cosmetic unless encryption or trusted computing is involved. I agree with you that tokens aren't inherently better. Many auditors are completely clueless.
    – amon
    Jan 30, 2021 at 10:37
  • Is your application intended to be used primarily/exclusively off-line, or is the off-lime mode a fallback for when connectivity to the server fails? In the latter case, how do you ensure the communication to the server comes from an authenticated user? Jan 31, 2021 at 10:21
  • @amon - after the initial authentication with the server, settings/config data is downloaded and stored in a local database (MSSQL or SQLite).Logging in when offline would just be to access this data (and data the user has saved).
    – playerone
    Feb 1, 2021 at 10:14
  • @BartvanIngenSchenau - offline was originally for when an Internet connection is not available (a lot of the users take a laptop to farms, for example). Admittedly, this isn't as much of an issue as it used to be, with 4G/5G availability.
    – playerone
    Feb 1, 2021 at 10:17
  • 4
    @playerone Any attacker that is advanced enough to decompile the app could just access locally stored databases directly, it seems. The proposed security methods (local authentication with password or token) are not a good fit for the threat model. It's a good mitigation against lesser threats like non-technical attackers though. The security level can be increased by encrypting the local database with a key that is only accessible through the user password. But that's still fairly fragile if there is untrusted software on the laptop.
    – amon
    Feb 1, 2021 at 11:06

3 Answers 3

1

I'd have to agree that a stored token doesn't solve the local attack problem.

Consider encryption.

The security model you're looking for is one where the thing doesn't work when the password isn't present. So store locally but encrypt data so that without the password it's useless gobbledy gook.

Don't store the password. Just it's salted hash. Since the attacker is local you have to assume they have access to everything stored in the clear.

The chief problem here is now you need a decryption layer when accessing data locally. This isn't a small architecture change. Don't cheat and dump decrypted copies on the hard drive. Your pen tester will find them laying around even after the password has been removed. Even if you delete them.

2
  • We assume, there was (at some moment) a connection between server and client for this last to get something to encrypted and decrypt. Offline modes should work even if you never had connectivity. Otherwise, what kind of offline mode is the one that first forces you to be online?!?!
    – Laiv
    Feb 1, 2021 at 16:12
  • @Laiv you can say that about every bit software you don't write yourself. Everything else uses a network of some kind at some point. Even if it's the sneaker net. Feb 1, 2021 at 17:25
0

The main issue they have is that user authentication takes place on the client, rather than the server.

So you do have a server?

a requirement from our customer is that the application needs to work offline

All the time?

Is there no opportunity to have the client "phone home" now and then?
It might be acceptable to generate a[n encrypted] Token on the server and store that locally, but have it expire after a period of time, at which point the User has to "hook up" to the server again and acquire a new Token.

3
  • It's not necessary to be offline all of the time, just when there might not be an Internet connection available. The program has to phone home already (the settings expire after a week of no contact with the server), but if the app is decompiled, I can't see how to stop a user from logging into it. If it downloads a token from the server, checking this could be bypassed in the same way entering a password could be.
    – playerone
    Feb 1, 2021 at 17:29
  • @playerone I can see one way to prevent the data being accessed without the password, and that is to encrypt the data with the password - but most apps don't bother with this. Can the app get the data from the server without the password, and if so, is that a problem?
    – user253751
    Feb 2, 2021 at 10:43
  • If the client app is "getting data from the server" then it is, in this context, online. Maybe not to the Wibbly-Wobbly-Web, but to the Server and that's what matters here. If the app is "online" (to its server), then authentication / token generation /can/ be done on/via/through the server, which is the only environment that you can trust.
    – Phill W.
    Feb 2, 2021 at 11:18
0

In addition to all the previous answers...

An offline mode can be as secure as its counterpart (online). The key difference between the two modes is all the actions you stop allowing due to the authorization need.

Offline modes should be compatible with the fact that some data won't be available or up-to-date and some changes won't be committed to change the server state or the state of data in the datastore.

However, it doesn't prevent you from allowing the user to "identify" himself on the client. Of course, its veracity remains to be seen, but this is something that will happen eventually. Eventually, all the changes will be authorized (or rejected). The offline mode can just postpone this last step.

Under the hood, it tracks and enqueue all the operations required to reproduce the client state on the server. Once online, if credentials bound to these operations are valid, the client push all the operations upstream and hope for the best.1

But you will find that such pre-authentication is useless and irrelevant for the whole process. And, as you know, insecure. So just leave the user to operate with the data cached on the client and once online and authenticated, do authorize or reject these changes.

Even if the server provides clients with tokens, public keys or certificates, these can change while the client is offline. By the time it gets online again, the secret key might have changed, the certificate could have expired or tokens could have been revoked. Even accounts cached on the client from previous logins can fail if they were removed/blocked on the server-side.


1: Why hope for the best? Because other offliners might have gone online as well, requesting a different set of changes on the same resources.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.