In web programming, a classic mistake is assuming that you can validate data by asking the web browser to do it. That’s roughly what went wrong between Tinker and WarCraft 3.

Tinkering

Years ago, I was working on a hobby project I later called Tinker. Tinker was a game hosting bot for WarCraft 3.

Hostbots are useful for a variety of reasons I won’t go into, but mostly I enjoyed Tinker as a technical challenge: a way to experiment with small amounts of reverse engineering, to explore programming techniques (e.g. actor model, strategy pattern, parser combinators), and to seriously try out some code verification tools (e.g. Code Contracts, Code Analysis, Pex, CHESS).

I did most of my reverse engineering by analyzing the information exchanged between Battle.net and the WarCraft 3 client. I would start WarCraft 3 and Wireshark, perform an action in the game, see what information was sent, figure out the structure of the information, and program the bot to mimic that structure.

Because I was inferring the structure of packets by observation, I’d often miss small details. I’d think some value was always 0, but it turned out there was a corner case where it was supposed to be 1, or whatever.

Typically, the consequence for getting a detail wrong was all of the players immediately disconnecting from the bot’s game, or the bot being immediately disconnected by Battle.net. An annoying but ultimately minor consequence, in the scheme of things. Typically.

Making a Game and a Bug

As a player, creating a custom game in WarCraft 3 is relatively simple: you choose a map and a game name then click “Create Game”, for the most part.

As a programmer, things aren’t so simple. You need to know the type of packet used to create a game, where the game name goes in that packet, how the game name is encoded (null-terminated UTF8), how maps are identified (path relative to program folder and a few sometimes-quirky checksums), where they go in the packet, what game settings there are, how they are encoded (bit flags), if there’s any sort of trickery to avoid zeroes because all these things are being shoved into a null-terminated string (yes), and etc. Remember: get a detail wrong, and your user gets disconnected instead of making a game.

Obviously, as part of writing a game hosting bot, I had to write code to generate ‘create game’ packets (a lot of the work had already been done). However, in doing so, I missed one important caveat: in Warcraft, the game name text box stops taking input after 31 characters. In fact, game names longer than 31 characters are considered invalid.

Whatever. No big deal, right? Someone will try to make a game with a long name, and their bot will get disconnected. They’ll contact me, give me the logs, and I’ll figure out the problem. Typical bug fix. Annoying for the user, but nothing serious.

No Games for Anyone

Things weren’t so typical, this time. I had no idea anything was wrong until I received a private message:

Urgent: HostBot



gamename = “0123456789012345678901234567890” // (legal)

gamename2 = “01234567890123456789012345678901” // (illegal) You need to implement a max gamename length to your HostBot program NOW. If a game is hosted on a server with a name that is longer than the max game length imposed by WC3, everyone who views the Custom Game list on that server gets instant disconnection [emphasis mine]. It appears the max gamename length is 31 characters. I love your HostBot program, don’t get me wrong but… your software is the only freely available software I know of that can create this problem, and its been happening frequently (once every couple of days on USEast, the custom game list goes down for hours at a time). Its pretty hard to believe that Blizzard have left such a problem in Bnet, but their software was never setup to deal with the freedom your HostBot currently gives. Thanks!

Oh Sh-…..oot. Tinker allowed too-long game names, and the Battle.net servers were accepting them! The servers would then broadcast the invalid names to any WarCraft 3 client that asked for the custom games list, causing the client to disconnect from Battle.net. Users of my bot were accidentally performing denial-of-service attacks on the custom games list and taking it down for the entire realm for hours at a time!

Hundreds, maybe thousands, of people were being actively inconvenienced by a mistake I made. I fixed the bug as quickly as possible. I informed Varlock/hogantp, maker of the better-known GHost. I informed Blizzard.

I was a bit worried blizzard would just ignore the issue, becauset of my experience with them chronically ignoring suggestions made by the mapping community. However, a few days later, sending a too-long game name would correctly disconnect the bot instead of everyone else. Maybe Blizzard noticed the problem on their own.

Summary

Users of Tinker were accidentally preventing everyone from playing custom WarCraft 3 games, because I didn’t realize (and Blizzard half-forgot) that game names were required to have fewer than 32 characters.

My bug performed a (sort of) distributed denial of service attack on (a subset of) Battle.net. My bad.

(Fun fact: being a programmer lets you make bigger mistakes. I think my mistake inconvenienced on the order of ten thousand people. That’s a lot, but laughably small on the scale of things programmers have messed up.)

—

Discuss on Hacker News, Reddit

—



Twisted Oak Studios offers consulting and development on high-tech interactive projects. Check out our portfolio, or Give us a shout if you have anything you think some really rad engineers should help you with.



Archive