22

I'm cross posting this question from Programmers.SE because I think it's equally on-topic here and would like to pose the question to this community as well.

This seems like a programming question but it's really a fundamental security question too.


Is it fundamentally possible to validate that an unmodified version of your client connects to your server?

I was just thinking about the idea of having my client-side app hash it's own source code and send that as a key to the server with any requests as proof that it's unmodified, but that's silly because anyone could just have the client send a hash of the unmodified version via a modified version.

I was wondering if there might be a secure way to do this though, via some sort of proof that the client was unmodified.

  • 1
    Regarding your "password" approach, this is exactly how API keys work. However, that will only uniquely identify the user; it will not verify that the user is using your original software (rather than, e.g., a written-from-scratch clone). – apsillers Sep 23 '14 at 18:55
  • 7
    If you think that validating the client is the solution, then you are asking the wrong question. – rook Oct 31 '14 at 19:29
  • 16
    Your application is a guest on the attacker's machine, and guests need to follow the rules. The attacker makes all of these rules. – rook Oct 31 '14 at 19:39
  • 5
    It has a name. Know it. "Remote Attestation" – Joshua Oct 31 '14 at 20:55
  • 4
    In the bad old days the server for the Windows version of AOL Instant Messenger sometimes sent a challenge. It was an address in the code space of the AOL-furnished client, and the client responded by sending whatever binary data was at that location in that version. A wrong answer resulted in a server-initiated disconnection. – O. Jones Nov 1 '14 at 18:38
37

It is fundamentally impossible to validate a client on a system you don't control.

That doesn't mean it can't be done to a sufficient degree. eBook readers, for example, generally try to ensure the client is authentic. They (seem to) do so in a manner that is secure enough to defend against their threat. Good enough to protect nuclear secrets? No. But good enough for their threat environment.

Figure out how important that control is for your application, and determine the compensating controls you'll put in place to limit the damage when someone goes through the trouble of ripping apart and then mimicking your application. Don't think in terms of black/white, possible/impossible; think in terms of acceptable and achievable security.

  • 10
    In other words, it boils down to the old joke: You don't have to run faster than a a bear to escape it; you just have to run faster than your friend. You have to make it annoying enough to reverse engineer your application that people will go after something else (like downloading videos using bittorrent rather than your video-on-demand service). – ntoskrnl Nov 1 '14 at 14:18
  • Not sure I understand why this is correct. A hacked client needs to mimic a valid client. The hacked client cannot always be precompiled, because that would require reverse-engineering the original client which is equivalent to solving the halting problem. Therefore, for a sufficiently complicated client, the imitation must interpret the code on the fly rather than recompile it. That necessarily introduces extra delay, which can be detected by the server by measuring response times. Hence it should in principle be possible, shouldn't it? – Mehrdad Nov 2 '14 at 10:41
  • @Mehrdad If you like hypothetical reasoning then you should also take into account the speed up theorem which basically says that: no you can make the interpreter run as fast as needed, given enough resources. – Bakuriu Nov 2 '14 at 12:25
  • @Mehrdad: any VM is essentially an interpreter; clearly the perf cost here isn't necessarily huge. – Eamon Nerbonne Nov 2 '14 at 13:23
  • 1
    @Mehrdad You cannot (or at least should not) rely on response times in a client/server environment that runs over the Internet, at least with any level of precision necessary to do what you suggest. You have no idea what kind of connectivity the client has, what happens to the routes each packet takes, and how many people along the way are trying to stream Netflix along the way... – lc. Nov 2 '14 at 13:56
19

It is fundamentally impossible to validate that an unmodified version of your client connects to your server.

... unless you do what is necessary to ensure it. This means client-side tamper-resistant hardware.

When your code runs on the client's computer, the computer owner can run a debugger and modify the client code at any point with arbitrary values. The "debugger" can be a full-blown virtual machine. If you want to avoid that, you can try to engage in an elaborate hide&seek game where you imagine extra detection systems, and attackers counter these with variants of their own tools. This is the problem of people trying to design anti-cheat software solutions (e.g. PunkBuster); this is also the problem of people who want to sell Video-on-Demand services while preventing the customers from saving the videos locally and then publishing them on various file sharing platforms.

To sum things up, these protections don't work well, even when the data to protect is as trivial as extra lives in some game.

To avoid this, you have to make your code run on protected hardware, that will defend itself against deep inspection from its presumed owner. This is the model of gaming consoles, payment terminals and smart cards.

A TPM is an attempt at a compromise: a tamper-resistant module running within what is otherwise a normal PC; the assumption here is that a normal user will find it too hard to modify the hardware to, for instance, read and write all the RAM without going through the pieces that are under supervision of the TPM module (e.g. the CPU).

Without such hardware on the client side, what you are trying to do will not work. Unless altering the client code would be so worthless than nobody even tries. It all depends on the value of what is at stake here.

  • 4
    And even then the cat and mouse just moves into hardware via mod chips. I suppose the end game looks like attackers fabbing complete chip clones with modified TPM blocks. – Zan Lynx Oct 31 '14 at 20:12
  • The step in the cat and mouse game beyond that is hardware that has anti-tamper sensors in the enclosure and will wipe itself if they go off. Even that will probably fail against a determined attacker with deep pockets for anything in the mass market since the attacker can just keep buying more until they eventually defeat the intrusion detection system. – Dan Neely Oct 31 '14 at 21:16
  • @DanNeely: Actually, I believe if you keep the original chip around you can probably pass the authentication requests in and out of it. You might even be able to do the network encryption through it as long as it doesn't check that the encryption request comes from an authenticated execution page. – Zan Lynx Nov 1 '14 at 0:59
  • 9
    So, the problem of "program running on a computer controlled by client" is reduced to the problem "how do I ensure total control over client computer". – Peteris Nov 1 '14 at 10:19
  • 1
    @Peteris Which, coincidentally, happens to be something very desirable to malware writers. – Riking Nov 2 '14 at 9:09
11

You could try Cryptographic Obfuscation when it exists

Cryptographic Obfuscation is were, in certain senses, you make a programs source code unreadable. What you can then do is hardcode a cyrptographic key into the program. You would also want the server to supply a random seed to your program since the computer could not be trusted. The only problem with this approach is the Cryptographic Obfuscation is that it has not yet been implemented, and also that only certain senses of it are possible.

  • I read through it; very neat, and very much an answer to my question, as a whole. – Viziionary Nov 1 '14 at 3:15
  • @jt0dd It is possible to change what to accepted answer is in case you are wondering. – PyRulez Nov 1 '14 at 3:32
  • 4
    Well the article explores the subject in depth, but your answer doesn't / doesn't have important parts such as a clear answer to the question (which is "no" it seems). Your answer would need to discuss the relevant contents of that article though. +1 for the article though, very interesting – Viziionary Nov 1 '14 at 3:37
5

I too have approached an issue such as this with the company I work for. after weeks of working it out, the answer is its not really possible.

And here is why:

You're basically encountering a "Trusted Client" problem. The client code runs on the user's PC, and the user has full control over the PC its originating from. The user can change the bytes of the program on disk, or even in memory in some cases. If you were to try to perform a hash or checksum against the code, he could simply change the code that did that verification and make it return "unmodified". Its a smoke and mirrors tactic.

You could try to make things a little harder on a malicious user but there's no practical way to achieve what you're hoping. Not without it becoming a large headache.

3

You can use HTTPS together with client certificate authentication. Then you can ensure that only clients with a valid certificate are able to use your site.

The client certificate will then replace the password you mentioned and the user will not notice the magic done in the background.

  • I don't think our customers will be willing to hassle with a certificate. I wish they would, but people find that a pain. – David Thielen Sep 23 '14 at 19:02
  • 1
    @DavidThielen you can create a certificate with the first start of the application and use this. Then your customers don't even know this. The security is weakened then but in your case it should be OK. – Uwe Plonus Sep 24 '14 at 4:28
  • 1
    If the app on the client system creates the certificate the first time it runs, how do we know when it is used that it is truly from them. Do we trust that first time and then we're safe from then on? Thanks – David Thielen Sep 24 '14 at 16:54
  • 1
    Yes, you trust it the first time and save it then. So at the second connection the client is already known. – Uwe Plonus Sep 24 '14 at 19:54
  • 1
    Thank you. If I could select two right answers I'd select this also. – David Thielen Sep 24 '14 at 22:50
2

If you want to uniquely identify the user, API keys will work well for you. In order to use Facebook's API, or Stack Exchange's API (etc., etc.), you'll need to get an API key to identify yourself as a particular user of the API and send that API key with every request. Thus, every request that hits the API can be traced back to an originating user. This also allows the API owner to control who accesses the API by restricting who is allowed access to an API key.

However, that will only uniquely identify the user. It will not verify that the user is using your original software (rather than, e.g., a written-from-scratch clone). Verifying that the user is using your original software is virtually impossible, since it relies on the assumption user doesn't have control over his or her own computer and can't, e.g., run the program in a debugger and change software instructions at will.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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