Saturday, July 5, 2008

If you have not bought or sold something on Craigslist, or at minimum browsed your particular region's Craigslist section, you truly have not experienced the best that the Internet has to offer. I use Craigslist probably half a dozen times per year for legitimate reasons -- to sell something I want to make a buck on or simply cannot bring myself to throw away, or perhaps I need to buy something particularly exotic or maybe something I'm looking to get on the cheap. The remainder of the time I'm cruising Craigslist purely for entertainment purposes. The "Best of Craigslist" and "Free" sections consume the bulk of my time.

Thursday was one of those days where I was posting an item for sale on Craigslist. I received the email that contains a link to publish, edit or delete my post, and at that moment my subconscious tazed me and told me there was something of interest in that link. It was not too unlike other links I have received in the past from sites that require me to verify that I do, in fact, own a particular email address. It contains a link that, among other things, contains some seemingly random garbage either as part of the URI or as part of the query string. This "random garbage" is generally an MD5 checksum or similar mechanism that ensures that it cannot be easily guessed and allows all involved parties to sleep comfortably knowing that posts cannot be tampered with by anyone other than authorized parties. Poor ways of implementing this would include anything that bases the MD5 on anything that can be easily guessed or otherwise obtained. Obviously, if the system in question simply MD5'd the poster's email address and posting title, a little trickery would get an attacker access to the management of that particular post.

When I received the email the other day, I quickly parsed through the past ~3 years or so of Craigslist posting emails and quickly noticed there was a pattern. All posts are of the form https://post.craigslist.org/manage/[8 digits]/[5 lower case letters or numbers]. I legitimately thought I was on to something. A few bogus posts later (which subsequently got flagged. Thanks, Craigslist overlords!) I was wondering, could it really be this easy?

As it turns out, no. It is no simple task to defeat Craigslist posting security. The first 8 digits in the path are easily obtained. In fact, they simply correspond to the posting ID which is freely available from any posting. This brings up two interesting points:

This provides no security, and in reality probably was not chosen for security reasons

Craigslist cannot handle more than 10^8-1 (99,999,999) posts in any one posting window, which is typically 7 days. This presents a curious DoS condition that is probably entirely impractical, however is interesting to consider.

This brings us to the last 5 characters of the URI. Another quick analysis of my posts shows that they are always 5 characters and only ever contain a mixture of numbers and lower-case characters. The mathematicians in the house have already busted out the answer on their pocket calculator, however for those not so inclined that means there are (26+10)^5 possible values for this field (26 lowercase characters, 10 digits, 5 places, which results in just over 60 million possibilities. 60,466,176, to be exact).

If those 5 characters were based on something that could be easily guessed or obtained, there would be cause for concern, however no correlation was determined between the 5 characters and the following characteristics:

Poster's email address

Posting title

Date/time

Post ID

This leads me to believe that it is a randomly generated string of some sort that serves as an index into a database of posts.
Anyone that has ever had to develop, enforce or audit a password policy knows that a 5 character password, regardless of content, is prone to failure. In this particular case, however, is it adequate?

In my opinion, yes. Given the nature of how Craigslist posts are managed -- HTTPS -- and the relatively limited time window in which the management URLs can be accessed (7 days for most posts, 30 for a limited few), the chances of someone brute-forcing these seemingly simple 5 characters is virtually 0. Since these require HTTPS posts, even if you can pull off 1 per second, it will still take you nearly 2 years to guess the correct URI ((26+10)^5)/60/60/24) == 699 days). By the time you guess it, the post will have expired or been deleted, and on the off chance that you get lucky and it still exists, you will almost certainly have tripped up something on Craigslist's side and Craig Newark himself will be on his way to your house to slap you around.