More of a security type question.

Started by
8 comments, last by Dave Weinstein 10 years, 9 months ago

I am making great progress on a little online game I am programming.

The thing is that features (not to be confused with feature creep) and minor bugfix changes are occurring at a rapid rate - daily.

What is the easiest way to keep a client upto date with changes happening to frequently?

One thought I had (yes you will scream at me for this), is to have a persistent R/O SMB share and actually execute the game itself across the internet (all of the media will still be installed client side) so the executable itself would be far less than 100kb. This way, once approved changes are made and the executable is placed on the share, everyone would be upto date at next program launch.

I was thinking of having the exe stored on a Raspberry Pi, so there wouldn't be any other critical files that a hacker could comprimise. Just have it dedicated as the 'LaunchPad' server so to speak.

The installer package would install media and the link to the exe '\\servername\program.exe'. Bandwidth shouldn't be a real issue I wouldn't imagine. On a 200Gb allowance this should cater for a max of 2097152000 program launches per month (excluding overheads and other internet factors).

If I got anywhere near this figure then I would have to obviously look at a more robust approah as 2097152000 hit, might be an indicator of a somewhat successful game.

The main concern is hacks to the server with an open SMB port. Unless there are other factors I have not even considered.

What are your thoughts on this approach?

Advertisement

That's a really really bad idea.

If you want to download executables off the network for updating, you're going to need to strongly sign them, and then have the installer (and auto-updater) verify the signature of the executable on download.

Copying it off of a random network share is just unwise.

Thanks for the reply, but the intention is not to download off random shares as such. But, to execute them directly from my share.

But, I do get where you are going though. It wouldn't be hard for someone of malicous intent to redirect the shortcuts to their own share.

Back to the drawing board. Hehe.

+1'd you for that one. ;)

What's wrong with an auto updater that checks on launch for new updates and uses an incremental diff system? That saves a lot of bandwidth and is the preferred choice. It's not like you will be updating your server patches twice per day on average, won't you??? (that would be a terrible QA dept issue)

If the update is critical (i.e. protocol change, extremely hot security vulnerability fix, etc) you can have the protocol so that the server kicks the client and let the client know it was because the auto updater needs to be launch.

Although if you're disconnecting your users too often, they're gonna be pissed.

True, thanks man. :)

I would do something along the lines of what Matias Goldberg suggested.

One additional thing you could do is torrent your updates (if, for example, you had very limited bandwidth (or speed) on your server). Your users could each act as seeds from which another user can download from. This would probably be a good amount of work to implement, but I can imagine it would be a fun and educational adventure.

You'll also certainly want to digitally sign your updates/files (like Dave suggested), just to ensure that nothing is corrupted (or hacked (or fake)).

[size=2][ I was ninja'd 71 times before I stopped counting a long time ago ] [ f.k.a. MikeTacular ] [ My Blog ] [ SWFer: Gaplessly looped MP3s in your Flash games ]

"What is the best way" kind-of depends on what your requirements are.

If all the testers are within the same local network, where you trust all employees, a SMB share might work fine and be simple.

An alternative would be to have your automated builds generate an installer and upload it to a server; have the game launcher download and run this installer every time it's launched. As long as you can control the DNS and server you get that from, this can be safe enough for a small set of testers.

Finally, for widespread deployment, you need to use HTTPS for download, with both client and server certificates, and verify some kind of signature for each update downloaded. You also want to make sure that you don't download a new version unless the currently installed version is out of date.

enum Bool { True, False, FileNotFound };

Finally, for widespread deployment, you need to use HTTPS for download, with both client and server certificates, and verify some kind of signature for each update downloaded. You also want to make sure that you don't download a new version unless the currently installed version is out of date.

I think you could even do without HTTPS using server certificates, and possibly safer, too (though HTTPS is surely the easiest, most straightforward solution with readily available libraries).

Server certificates are not "safe" or even "trusted". They're something you get signed from a company that takes money so you have the feeling that you should trust them. If that company's private key is compromised (DigiNotar, anyone?) anyone could pretend being your server.

Instead, you could trivially sign (or "sign" by encrypting) your update file using an arbitrary private key (which except while signing you keep on an USB stick around your neck, if you wish), and hardcode the public key into the client. Then download updates via a normal unsecured connection from your server. HTTP, rsync, torrent, FTP, or even a raw socket, or SMB if you want (though I would definitively not want to put SMB on the internet...).

You could probably abuse good old curve25519 for a really really barebones "encrypt signing" by encrypting the install file with a block cipher, then doing a half DH with the symmetric encryption key when packaging the update, and doing the other half DH on the client later (of course one could use the "ed" version instead of this crutch (which does actual signing), but I've never worked with that one, so I couldn't tell much about it).

Anyone knowing the public key (so, anyone having the game client) will be able to do the 2nd half and thus derive the symmetric key used to encrypt the update. There is no big secrecy in that system, but you don't need/want that. It doesn't matter if the NSA reads the contents of your game update.

Someone not knowing your private key can of course do the first half of the DH too, but they can't do it so the derived key deciphers the update to something meaningful (or something that matches a checksum that you'd embed at the end of the encrypted stream, for that matter).

Yes, anyone could hack your server or could tamper DNS to redirect users to their own server to download their (malicious) updates instead. But none of these will decipher (or give a valid signature) using the public key hardcoded into the client -- so, who cares. The worst thing to happen is that users download updates that will fail to install with an error message. That's admittedly annoying, but there's not much you can do against it.

If someone successfully tampers your DNS server, you already have lost. Next you would need to protect against someone digging up the ground and pulling out the cable. There's things you just can't protect against.

Of course, if you pull an Opera and have your code signing certificate stolen, you're in big trouble... but there's hardly a way to be 100% safe against such a thing from happening, you can only avoid the most stupid mistakes (such as storing it on a computer with internet connection, or even a server).

But as long as a key exists, someone can in principle steal it, if nothing else, then by breaking and entering, and putting a gun to your head. It's doubtful whether your game is worth such a risk, though.

Finally, for widespread deployment, you need to use HTTPS for download, with both client and server certificates, and verify some kind of signature for each update downloaded. You also want to make sure that you don't download a new version unless the currently installed version is out of date.

I think you could even do without HTTPS using server certificates, and possibly safer, too (though HTTPS is surely the easiest, most straightforward solution with readily available libraries).

Server certificates are not "safe" or even "trusted". They're something you get signed from a company that takes money so you have the feeling that you should trust them. If that company's private key is compromised (DigiNotar, anyone?) anyone could pretend being your server.

You don't have to get your certificates from a certificate authority. You could easily just create your own. The game update gets downloaded through your own game client, not the user's browser, so certificate authorities are much less meaningful.

[size=2][ I was ninja'd 71 times before I stopped counting a long time ago ] [ f.k.a. MikeTacular ] [ My Blog ] [ SWFer: Gaplessly looped MP3s in your Flash games ]

You could easily just create your own. The game update gets downloaded through your own game client


My point exactly. Use self-signed certificates when you control the establishment of the TLS connection, and ship the appropriate client-side certificate with your initial installer.
enum Bool { True, False, FileNotFound };

This topic is closed to new replies.

Advertisement