What does secure mean? For most people this means that a site or server that cannot be hacked.
In May 2013, one of the largest Banks in America (Bank of America) with
the one of the most secure banking systems in the US was hacked. The hackers took
over ATMs in NYC and in just 4 hours withdrew 20 million dollars from user accounts. This is just a few months ago... this is supposed to be security at its best. In July 2013, Apple was hacked and their developer accounts were compromised possibly exposing all developer accounts. Their email (which I received) said that all developer accounts were encrypted but that they were going to reset all developer accounts "just in case."
For the BofA atack, there are some minor caveats like the hackers had internal information, but that hardly matters... how did the hackers get in? The hackers having internal info should not have allowed this. At Apple, no excuse was offered but how did this happen? This is a huge deal but what about that encryption... does it matter?
The big boys who have enormous resources and fabulous teams of anti-hacker developers still manage to be hacked. If they are hacked, what can a lowly game developer hope to do against the onslaught of hackers out there. So, before you get upset, there is a ton that you can do to prevent the very thing that caused so many problems for Apple and BofA. It comes down to architecture.
Before I begin, let me say for the record: you must make an effort to thwart hackers to prevent the casual hacker or lazy programmer from getting into your system. That said, I
promise you: you cannot build a better security system than BofA. The
trick is to limit the damage and to detect the intrusion. The rule is: Build the best system possible but also realize that hackers will break into your system eventually. This is where a good architecture matters.
Any place where external users can attack your systems, or just use your systems, you have a potential threat and a vulnerability. Most people look at game network systems as being something like this:
Each part of this diagram has a ton of vulnerabilities. The phone or PC can be hacked, the users can snoop on their PC and then replay the data traffic to the server, a man-in-the-middle can listen to someone's network traffic and try to pretend that they are making purchases, someone can attack the server directly sending bad packets or good-looking data that is meant to take over your sever and give them access to your database... and on and on. Where do we server programmers have any control? Only at the server level? Not so fast... we have far more control than that.
We can control the client app, we can hash passwords before they are sent and never store passwords on the server (you store the hash so if hackers get the DB, they still can't use the stolen accounts ), the communications can be controlled and if at any time we detect abuse, we can shut down an abusive connection, etc. All of these are potential places to prevent hacking (and optimize).
The biggest problem with the above diagram? The direct access of the server to the DB. In fact, this is so flawed, that you are practically giving hackers free access to the db and you will never detect an intrusion when it happens because most likely, they hackers will take over the server using buffer overflow and then simply copy everything on your server so that they can look at it during leisure time. They tend to target specific database items but when they don't know what they are doing, they may just copy everything.
The communication protocol should be small and will be the topic of another blog post.
For
any internet facing process, I prefer to store nothing like a password
file with the exe. My type of security is to write an exe that:
1) Can be launched remotely
2) Can be isolated in a VM or on it's own hardware
3) Has no DB access
4) Opens a socket on launch and takes commands like "listen on port 3400" and "forward all packets to ipaddress 10.1.34.192".
5)
Isolate that machine/VM in such a way that when hackers break into it
(they always do) that they have no configuration data, no local files,
no db access, etc. This prevents them from knowing anything about your
systems.
6)
Keep a monitor application that checks to make sure your app is still
running and when you app comes down, relaunch, send parameters for
configuration to your app, and no worries...
They
hacked your system, but you can rest assured that even with buffer
overflow and if they manage to send your exe back to themselves, they
won't know anything about the internal configuration of your systems
since you app doesn't know those things.
No
system is perfect, but this type of system is extremely difficult to
take over the server, and when they do, this "gateway" type of app knows
nothing so hackers don't get anything and they certainly have no access
to user accounts.
Storing
anything in a local directory leaves you vulnerable. If you want to do
this, then unix/linux is the best way because you can lock down the file
system to prevent hackers from looking at your files (Windows can be
configured this way, but it's a lot harder to do).
So,
for a local file, limit it's access to read only (you won't believe
what they can do if they can overwrite your password file... it's a
backend buffer-overflow where they overwrite it and when you decrypt it,
your app crashes). Then put your app deep in a separate subdirectory
that can access from your file. Then give your app limited permissions
(definitely not root). Deep directories make it harder to get to /etc
and other directories. Here is some good advice (jail kit stuff):
http://stackoverflow.com/questions/527876/how-to-restrict-a-linux-user-to-be-only-able-to-read-home-user-and-nothing-else
When
they take over your server (and they will, make no mistake), make it
very difficult to change directories, grep, etc. You don't want them to
find anything. Anything that they find could become a vulnerability. Its
best to start with a fresh install on a clean box and not install
anything on it that isn't absolutely necessary. A VM is great for this
because it's just a file. When you finish configuring the VM the way
that you want... copy the VM file and expect some hacker to get into
your system and completely destroy your VM. Then you can simply restore
from backup (file copy... really). Should take about 30 seconds to bring
your server back up.Whatever
you do... do NOT store a list of ip connections, ports, or access to
your DB. Never, never, never let your internet facing gateway process
have access to the DB. Don't even include the DB Connector code and do
not install the ODBC on that computer
either. You do not to give hackers even a small chance of figuring out
that you use SQL Server (MySql, Oracle, whatever) so the less info you
have on that internet-facing box, the less damage they can do.
This
is the current server architecture that I have built (a diagram I use
internally) and the gateways run in a completely different VM. All of
the games run on another box and cannot be accessed from the gateways
except through internal routing. When someone hacks the gateway, user info is never exposed.
Another
critical piece is the trapezoid that reads "Is user permitted". This is
in the gateway, but for malformed packets, too many packets in a short
time, buffer overflow, etc, I shut down the connection. Because we want
hackers to think that they are being successful and not know that we
spotted them, we put the socket on "ignore-mode" which means that it
continues to receive and will shut down the socket after 30-130 packets
later. That way, this increase the amount of work that a hacker has to
do by at least an order of magnitude.
The
other systems have a distinct protocol for talking to the gateway which
is highly specific. This protocol is different than the protocol for talking to the client. When hackers do take over the gateway, they have no
way to talk to the game servers, they have no access to the DB, they
can only talk on specific ports and IP Addresses. This system is not
unbeatable, but based on 20 years of networking security design, this is
my latest and most secure.
Splitting
your DB into sensitive data and common data can help too. If a hacker
has to go to different DBs (schemas) to try and get user account info,
this begins to become too hard to make things worth it. Splitting user
account info (credit cards) and purchases is trivial in the DB World,
but piecing those back together is very hard. Using an 'd' field is often trivial to replicate so I bind them using a "UUID" so that putting it all back together is next to undecipherable.
One
last step I do is never, ever, send user db indices (id) back to the client.
Way too many flaws in security are based on handing back to the user
their DB index (e.g. user_id=42336). If a hacker gets a hold of your db
through SQL injection, we don't want him to dump the user table by
knowing the structure or using simple indices. For each user, I generate
a unique identifier (UUID) that is sent back to the client. When they
get a list of friends or other things, you only see these impossible to
hack UUIDs. Hackers would have no idea how to use that information to
look up user info. The gateway knows nothing about UUIDs either and so hacking our gateway reveals no user info at all.
Encrypting packets will come next
1 comment:
Keep it up. I really like effort. parking luton airport
Post a Comment