26 April 2008
Many popular services online give out code snippets to place on your site for various reasons. Usually there's nothing wrong or dangerous about it, however, sometimes the opposite is true.
Take the insanely popular Google Adsense service. The idea is awesome, the implementation however - not that much. There is one line of code that scares me in particular:
<script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
How incredibly insecure is that? By placing Google ads on your website you are pretty much putting your security in Google's hands. If an attacker would gain control over the cluster that hosts the "show_ads.js" file, we could be talking about the largest mass-deface in the history of the internet. Worse, the attacker could quietly collect cookies from thousands of websites, and then commit massive identity theft (although, technically, the amount of traffic involved may be overwhelming).
To tell the truth, I can't exactly claim I never did the same mistake. Actually, I have the Google Analytics script embedded into all of my pages right now.
I guess you can agree with me when I say that the chances of Google getting hacked are close to 0. Consequently, I'm not planning to remove the Analytics script from my site anytime soon. However, Google aren't the only ones who ask their users to include remote scripts.
Don't believe me? Take another example. Digg.com. Guess what's their solution for placing a "digg it" button on your site?
<script src="http://digg.com/tools/diggthis.js" type="text/javascript"></script>
Yes, you can argue that digg.com is a pretty secure place as well, sure you can, however that would be missing the point. By placing this code on your page, you're trusting the admins of another site to be responsible for
your site's security.
What's the solution? Iframes, maybe. Giving out the script files for local inclusion, maybe. Anything other than including code from servers that the user isn't responsible for.
I doubt anyone that manages services such as Google Adsense will ever read this post, but if you're someone who's including remote scripts on a website, always remember that what you're doing is insecure.
Oh, and P.S.
Flash (swf) ads can also run scripts. Guess how many websites embed those remotely?
Posted by: kGen | In category: Webappsec | Comments (0)
29 November 2007
Seems that I forgot about this blog for more than a month now, and without any good reason. Anyway, I'll try to point out some ideas in this post, things that I've been dealing with lately. (Note that this post is in no sense a practical example of anything, but just a compilation of some theoretical points)
I'm currently finishing up a little project of mine, that just happens to be a multilayer poker game for cellphones. The client is written for Java MIDP, and the server is a standard multi-threaded Java application (running on a remote server). While working on this game I've encountered many security aspects that are worth sharing, so read on.
Game servers aren't exactly perceived as "web applications" in the standard sense, i.e. they do not utilize the HTTP protocol, use CGI, or depend on web browsers. And yet, they surely are web applications in every sense. They are very processor intense applications, and the developers usually focus on efficiency rather than security - in a classical trade-off.
There are a few core security mistakes that can be embedded deep inside the application design and render the whole game vulnerable to cheats and hacks. Here are a few:
1) Trusting the client-side for any calculations.
This an absolute NO-NO when it comes to game servers, or any multi-client servers in general. In my poker game the client has a state variable that says whether it's the players turn right now. This affects the menu options and the messages that will be sent to the server (on KeyPress events).
If the server just listens to incoming packets and handles each one without verifying their validity, it would be possible to make game actions before getting the "right" to do them. The server must hold all state variables and verify every action that the user takes.
In more complicated games "taking the client for granted" could result in things like speed-hacks, walking through walls, or worse. Never rely on timing or game logic to be made on the client side.
2) Sending all game information to everyone.
As a rule of thumb, no client should receive any information that isn't going to be used by it. Not only will such information give an unfair advantage to cheaters, but it will also utilize unnecessary bandwidth, that is already scarce.
My poker game has a few objects that represent the current game-state. One Game object and many Player objects. The Game object describes a poker table, and everything on it (including references to the Players). The player object contains all information about a single player.
When an event occurs, all the clients should be informed about the change. Now, I could just serialize all objects, pack them, and send them to every client. The clients will just take whatever they should, and leave all the unnecessary data untouched.
This is fundamentally not-okay. A cheater could tap into the incoming packets, and get all the "unnecessary" data just as well. In my case, this data would contain the other players cards. In poker, this is the ultimate cheat.
In order to avoid such situations, I didn't program the server to simply multi-cast everything. Each client has a separate TCP stream, and a separate thread. Every Player object has 2 serialization methods. One for public access, and one for private. A client that owns the current Player object will get all the data the object contains, while everyone else will only get the public data.
3) Be careful with persistent data storage, especially SQL.
Even in a simple poker game, persistent storage is necessary. My game has an "Accounts" table that contains login details, and various game data (like the amount of money a user has).
I refer to the database in 3 different "places" (per client thread):
A) Login attempts
B) After every turn (to update the stats and money)
C) When the user quits the game.
This is enough to prevent any "money loss" even when the server shuts down in the middle of a round, and far from enough to cause any serious server stress.
This approach is fine, unless you forget a very basic thing. Your server can be prone to SQL Injections just as the next php script. You have to filter everything you receive from the clients (strings, commands, etc). Whatever you intend to put in a query, has to be filtered.
Try to make less SQL queries, and more handling within the classes and objects. All the queries should be simple SELECTS or UPDATES, but nothing too fancy. This will save you CPU cycles, and leave your code less database dependent.
4) Multi-threaded is good, if you synchronize correctly.
Yeah, a basic thing like thread synchronization becomes a major security threat in applications such as game servers. Synchronization is made for the case in which the same data can be accessed from 2 threads simultaneously. When this happens, the results can be unpredictable. Or rather predictable, but very much un-intended.
Just as a single example, let's say that Thread 1 reads the variable "Money" and stores it. At this instant, Thread 2 does the same thing, and changes the value of "Money". When Thread 1 continues, the "Money" it stored will have the old value. If Thread 1 saves the value to the original "Money" variable, it will appear as if Thread 2 didn't run at all.
This can happen even with code that executes "instantly". It all depends on how loaded the server is, and the sheer probability of those 2 actions happening at once. This probability is especially high when the server is over-loaded, meaning that when the game "lags" it's the best time to cheat.
If the variable "Money" was locked properly, none of this would happen. However there is no simple "fix" to this. Synchronization is the essence of multi-threaded programming, and it's something you'll just have to deal with in your code.
------
There are more points to write about, but I will do so in another post. Meanwhile, it's sure visible that game servers are very challenging security-wise. The trade-off between efficiency and security has tremendous impact on them, and this makes them especially interesting applications.
I will write about this as I gain more experience in the field. Expect an update soon.
Posted by: kGen | In category: Webappsec | Comments (0)
8 October 2007
Proxies are a very vital resource if you want to stay anonymous online. Ofcourse, there are a couple of ways to compromise that anonymity, and I'm going to explain one of them.
True, you can't really get to the real IP address behind an "elite" proxy from the server side. However, let's not forget the client side, as it should provide us with the answer we're looking for.
Webapps today can easily send HTTP requests and even open sockets using stuff like AJAX (Javascript), Flash and Java Applets. Normally, you would expect the plugins to obey the browsers' proxy settings, but in certain circumstances this isn't so.
Sockets don't have to use the HTTP protocol, so they can't go through HTTP proxies by default. Even if you do use the HTTP protocol and connect to port 80, the system still isn't going to enforce the proxy settings on your connection. This makes sense, but also compromises the security a proxy can provide.
And yet, it just so happens that the JavaScript way to open a socket isn't cross browser, and the Flash way requires communications across an nonstandard port (1024+). This is bad for a couple of reasons. First, the server will have to listen on an arbitrary port, a feature that most web hosting companies won't provide (so this will require a dedicated server). Second, if the user is behind a firewall, the communications could be blocked.
For reference, here are two sources that demonstrate both ways:
JS:
http://ha.ckers.org/blog/20070926/de-anonymizing-tor-and-detecting-proxies/
Flash:
http://hackademix.net/2007/09/26/cross-browser-proxy-unmasking/
So, the last reliable way to bypass a proxy is to utilize a Java Applet. It can communicate through port 80, and JVM is a very trusted and popular plugin (usually built in). I've set up a small demo for you here :
http://own-the.net/ip/demo.php . Just set some proxy settings, and watch the applet discover your real IP.
You can get the .java source here:
http://own-the.net/ip/IpApplet.java . The source is commented, and pretty self explanatory. The "ip.php" file just echoes the $_SERVER["REMOTE_ADDR"] value within <ip> and </ip> tags (in an XML-like fashion).
Now you may think that proxies are dead, but wait just a moment. You can simply disable scripting, flash and applets in your browser settings, and be safe again. Remember to go "NoScript" every time you need anonymity, and it will be fine. Consequently, this anti-anonymization trick won't work on experienced users, but it will still help in 90% of the cases. This tactic still remains quite useful and accurate.
An that's it for now.
See you on my next post.
Posted by: kGen | In category: Webappsec | Comments (0)
Copyright (C) 2007-2008. Some rights reserved. Distribute freely, but don't forget to link to the source.