The Begining

I want to cover some of the common flaws I have picked up on in both major and minor 3rd party EVE Online sites, but first, some background, some tech and then forward onto the examples. It's been some months (maybe longer) since I last visited this topic, so let's just hope that anything I mention is patched. insert disclaimer

In the diverse and expansive universe of New Eden there are many aspects to the player community. Many of the community members are extremely dedicated to their super serious internet spreadsheets. Some of these players such as Fleet Commanders and Heads of Corporations are known as Content Generators, basically coming up with one reason or another to go to war with another group of players, organising the troops, creating the big battles and basically making things happen in the sandboxed game world. This is the primary type of content generator; the further up the chain you go, the more likely it's a mouth-breathing sociopath with an ego larger than he (and the odd occassion, she) could ever hope to flex in real life, leading to both intense space combat and orbiting a rock for 4 hours.

Alongside them is a different kind of content generator (though still likely some kind of egomaniac), and one of the aspects of the game that I found more appealing - the 3rd party developer. This was my role in various large player-run conglomerates. CCP graciously have provided multiple interfaces to interact with capsuleers of New Eden, albeit their APIs are often broken, unresponsive or simply telling you 'scotty the docking manager heard you talking shit about him', the APIs are there to extend the universe, which have been moulded into doing so.

Types of APIs

  • HTTPS XML
  • JavaScript IGB
  • HTTP Headers IGB
  • CREST (soon, tm)
  • Static Data Dump

Using only a single one of these for your application is arguably a bad idea, instead I recommend using them in a divine mess.

XML over HTTPS

This is the primary interface to pull data from the sandbox. Currently this is 1 way. This API is clunky, it's archaic and with many calls that don't really reflect the live state of the sandbox, just whatever was written to the database last, which can mean delayed and stale data.

There are 2 primary levels of access, public, and private. Public calls can be made without an API key and can pull non-sensitive data about characters, corporations, items or locations. Public API keys are generally used to retrieve information such as public alliance/corporation listings and lookups for character ID to character name and vice-versa.

Private calls on the other hand can be used to pull detailed information about characters or corporations, their assets, current tasks in progress, skills in training, outstanding market orders, how much money they have, or their last known location, ship type, etc. Private API keys in general are often used by players to use 3rd party applications such as EveMon, EveHQ, Neocom (iPad) or Aura (android) in order to track their characters progress and create plans for the future.

Access to certain calls are determined by a permission bitmask, assigned by the account holder who creates the API key.

Parameters to API calls (including credentials) can be provided by either POST or GET requests

Once a large corporation, alliance or coalition has formed, this is where the XML API becomes invaluable. This now gives community developers a way to authenticate members based on their in-game allegiances. For example, by providing a Private API key that shows all characters on your account, you can tie an API key to a user account, query the API key for its characters, their corporations and roles and apply your security model accordingly. A common use of this is assigning roles on a TeamSpeak, Mumble or Jabber server or a forum.

All API requests are logged and are visable by the key owners, including the IP address of the machine that made the call. It's recommended you know who is making calls to your account and remove any keys that show suspicious activity.

API Keys

API Keys consist of 2 parts - a KeyID, a seeminlgy sequential ID generated at the time of creation, and a verification code, a 64 character alphanumeric string generated by default, but is user assignable and can contain a larger character set, so dont expect this to be a particular format.

Along with the key itself, it has an expiry date, a bitmask for access, and a name for users to keep track of which keys they have created and where they are used.

From my experience, few users care about this, and over the course of running services have found myself being provided full access keys to high ranking spaseship generals' accounts. That to a virtual enemy, could provide valuable intel, location of key assets, war plans, and access to services such as enemy voice comms, forums and what have you. In fact, during a schism of an alliance I ran, a high ranking member who was given access to the key database, became an enemy shortly after and used the keys to gain intel. This was the horrible moment where it was up to the users to purge their keys, and a key blacklist became imperitive. To this day, I believe some of those keys are still active and are actively used by spies for virtual espionage, sabotage, asset thefts and other nefarious acts, all totally acceptable under the Eve Online EULA.

Caveats

You can also make the requests over HTTP and will be redirected to HTTPS. This really defeats the whole purpose of using HTTPS since the credentials and the request will be in plain text, which can be used to recreate the request. I think it would be in the interest of forcing good practice for CCP to disable the redirect and let broken code break, forcing the hand of application developers to erradicate this shortcoming.

Beware query string building with your parameters, use POST if you can and encode correctly.

Wrong:

$KEYID = '1234'
$VCODE = 'abcd&KeyID=0000&vCode=SomethingElse'

curl "https://api.eveonline.com/account/characters.xml.aspx?KeyID=$KeyID&vCode=$VCODE"

Right:

$KEYID = '1234'
$VCODE = 'abcd';

curl -X POST -d "KeyID=$KEYID" -d "vCode=$VCODE" \
https://api.eveonline.com/account/characters.xml.aspx

While the bug above is not a huge problem, considering the user would have access to credentials already it is still a bug nonetheless. Worst case scenario, it can be used to mask who is making the API calls, both originating IP in the API log and the user making the calls, potentially retrieving extended information than originally intended, but no more than you couldn't just call yourself.

The IGB

Eve's In Game Browser is based on Awesomeium. In short, it sucks... hard (CCP Please update it). However, there are 2 features that make it extremely useful to 3rd party developers; JS methods and extended HTTP headers.

Features are made available based on a level of trust given a matching URL pattern. Without regurgitating documentation pages from the evelopedia, a page can request trust for a url patten (this can be contain, or just be, a wildcard). Once a page is trusted, JS methods become available as well as the extended HTTP headers.

Suprisingly, users were quite wary of giving trust to unknown sites. At one point I wrote a page that would simply show and image, request trust, and poll the users location in the background. I would link it in local chat to enemies while a small gang were out roaming around looking for spaceship fights, trying to gather intel on what type of ship the enemy was flying, and if they were in a station or not. While this method was fairly ineffective in sparsely populated nullsec systems, there was slightly more success linking it in areas like trade hubs, with upwards of 1000 pilots in system. Generally, the intel gathered by this showed that most pilots would be in a starter ship and were likely new players on checking their info window. This in contrast to players living in nullsec who were a little more experienced and more likely to have used trusted sites previously. Further stats on this could be mildly interesting.

I had a very brief google about for vulnerabilities listed for Awesomeium and to my surpise I didn't find a single CVE - it definitely looks like a seldom explored area. Based on the amount of bugs found in most browsers and associated libraries it would be short-sighted to think there are no vulnerabilities here. That, however, is for another day.

Javascript Methods

JS methods in the IGB are very handy. They can be used to request trust, open dialogues, viewing the price of an item on the market, or showing a location on the map etc; they are mostly designed to be used with onclick events. With a little XSS on a trusted site, these can become very handy, I will get to an example of this later on.

No JS methods have return values, so this is pretty much a 1-way operation to the Eve client, so not quite as much mischief can go down, though there have been some very clever workarounds. Goonmetrics for example, a 2 part tool used by the alliance goonswarm and their allies which consists of a browser element that cycles through showing each item on the market in game. By doing this, it causes the EVE client to cache this data on the disk, where a desktop application reads the cache and then uploads the values to a web service and does some fancy spreadsheeting for supply and demand and making ISKies.

RTFM: List of IGB methods

HTTP headers

The IGB sends a bunch of headers based on the trust level, RTFM HERE

Static Data Dump

Though the Data Dump isn't actually an API, it's a database that is a reflection of all data in the universe that doesn't change. Locations, item descriptions / effects, Spaseships nomnom, distances between static locations and whole bunch of miscellaneous data neckbeards with neckier, greyer beards than my own, have found uses for.

I find the dump to be most useful for validating user input before making API calls. Not only is it much faster to query the db for an ID or name before making an API call to the XML API, but it's polite to not swamp CCP's API (or eve-centrals etc) with unecessary or invalid calls.

Maybe I should emphasis validaton. It's one of those extra steps that prevents your application from being a steaming pile of shit. Remember, the data in the dump is controlled. It's much safer to pass the controlled data onto the remote API than it is your user supplied data... I feel like a condesending asshole saying shit like that, but it would appear necessary.

CREST, Carbon Rest

CREST is CCP's one day replacement to the API, but with a much more glorious task in a way that resembles something from this decade. A RESTful JSON interface that allows users to both pull data and interact with the universe authenticated by the new SSO model (zomgcool right?). Currently CREST is in use connecting the worlds of DUST514 and EVE Online, and after being announced over 2 years ago, might soon(tm) be ready for the 3rd party devs to get their hands dirty. until then, we wait.

The most common fuckup: HTTP Headers.

I honestly suspect that the cause of this bug is that developers, somehow, have a fundamental lack of understanding of how a client server transaction takes place and assume that the client is somehow not under the control of the user or that the IGB headers can ONLY be controlled by the IGB. I'm not sure they've ever heard of Burp or Charles or just using modheader in chrome, which is how I prefer to develop anyway, considering how much of a pain it is to develop in the IGB.

Another reason maybe is because they don't know how to lookup the information, Alliance. Corporation and Character IDs are all readily available for lookup via the XML API. My prefered lookup method is using dotlan or evewho, inspecting the url to a portait or Corporation/Alliance logo will reveal the relevant ID. Ship, Item, System, Region and Wormhole ID's can be found in the static data dump.

Onto the bugs!

if($_SERVER['EVE_ALLIANCEID'] == '000000000') {
    // user is authorised
}

This approach is utterly useless, it's totally laughable and disturbingly common in stand alone scripts. Occasionally, its chained up with something like this:

if(strpos('IGB', $_SERVER['HTTP_USER_AGENT']) !== false && $_SERVER['EVE_TRUSTED'] == 'Yes') {
    //check extra headers
}

This provides zero assurance the client is using the IGB, however can be useful for modifying a view based on a guess it's really the IGB. Moving right along.

echo "Welcome back " . $_SERVER['EVE_CHARNAME'] . "!";
//Welcome back <script>alert('idiot')</script>!

I'm not really sure if people are on crack when they write rubbish like this, but it happens. A lot. It's been exploited at least once on somerblink EN24 to gain elevated privileges, I've reported the same bug to MonocleMadness and Evealopolous.. all in the exact same variable, in the same manner. Modify character name with malicious XSS prior to registration, register, perform some action (buy a ticket on a prize) to have your character name displayed on a page as a stored XSS/CSRF, steal cookie or worse, client side your target. Again the same bug on fleet trackers and similar for alliances I have been apart of.

It's not the most dangerous bug listed here. It's also slightly less trivial to exploit, which I'll cover later on.

While the XSS above is bad, it gets worse:

$query = "SELECT * FROM fleet WHERE character_id = " . $_SERVER['EVE_CHARID'];

This is particularly worse with PHP apps, where far too many developers have relied on magic_quotes_gpc or similar implimentations people use for when it's not enabled / available. the $_SERVER superglobal, unlike GET/POST/COOKIES is not effected by these ... protections... All of a sudden we've got SQLi in its simplest form. You would hope by now that developers have employed paramterized queries, at very least some kind of sanitization, unfortunately, it appears few of the developers in the community I would refer to as professional though the inverse of this is also true.

Final Update 2015

I had originally planned on writing more of this article and covering IGB javascript attacks and some other neat tricks but that was 2 years ago. Maybe I'll revist CREST now that it's out.

gr33tz: The Riot Formation, T'amber, Karbo, [CCP]PrismX, #eve-dev on coldfront and everyone who supported me and donated to fuel my evedev for the last couple of years.

Thanks to @snare for that time he tried to tell @charlieeriksen to hire me for the open position in Rekjavik in CCP's Sec team and I got denied.