Coding Horror

programming and human factors

I Just Logged In As You: How It Happened

In my previous post I Just Logged In As You, I disclosed that someone was logging in as me -- specifically because they discovered my password. But how?

If I wanted to discover someone's password, I can think of a few ways:

  1. Educated guess. If you know someone's birthday, their pets, their children's names, favorite movies, and so on -- these are all potential passwords in various forms. This is classic social engineering, and it can work; that's essentially how Sarah Palin's email was hacked. While my password was weak, it wasn't anything you could reasonably guess based on public information available about me.

  2. Brute force dictionary attack. If login attempts aren't meaningfully rate limited, then you can attempt a dictionary attack and pray the target password is a simple dictionary word. That's how one Twitter administrator's account was compromised. But failing to rate limit password attempts is strictly amateur hour stuff (and I'd argue borderline incompetence); no OpenID provider of any consequence would make this mistake.

  3. Interception. Eavesdrop on the user in any way you can to discover their password: install a hardware keylogger, software keylogger, or perform network sniffing of unencrypted traffic. If you have physical access to the user, low-tech analog methods such as watching over someone's shoulder as they type in their password are effectively the same thing. While I can't rule out paranoid fantasies of keyloggers, if my machine was so thoroughly 0wnz0red, I think my OpenID password would have been the least of my worries at that point.

  4. Impersonation. Commonly known as phishing. You present the user with a plausible looking login page for a service they already use, and hope they enter their credentials. Alternately, in the depressingly common Web 2.0 style, you can just demand that users give up their credentials for some trivial integration feature with the target website. I consider both forms of phishing, and I call it the forever hack for good reason.

So which of these methods did this person use to obtain my password? None of them.

It wasn't a guess and it wasn't brute force.

I guess I can tell you, so you don't fall into this trap again. There's a site I help out with that doesn't salt their passwords. They're MD5 encrypted, but if you've got a dictionary password, it's very easy to use a reverse-MD5 site to get the original. I was able to figure out you were a user on the site some time back, and realized I could do this, if only I knew your openid provider...

(As an aside, I complained to the head of the site months ago that he ought to start salting passwords for this exact reason. I also run my passwords I need to be secure through a few reverse-hash websites, just to ensure that it's not stored somewhere.)

So, the unethical part was actually looking up this information in the first place. I apologize. But like I said, better than someone else getting into this data.

Hey, it looks like you're storing passwords incorrectly!

we have met the enemy and he is us

We have met the enemy, and he is.. programmers just like us. Seriously, go read that blog entry. It is exactly, exactly what just happened to me.

When I say programmers like us, I mean me, too. I acknowledge that I am also at fault here, for...

  • using the same low-value credential password in two places.
  • picking a particularly weak password.
  • not using a high-value credential for something that clearly deserved it, namely, my moderator login to Stack Overflow.

All of this is true, and I shoulder the blame for that. Perhaps I should take my own advice. A moment of weakness, I suppose.

The important thing to take away from this, if you're a programmer working on an application that stores user credentials, is to get the hell out of the business of storing user credentials! As we've seen today, the world is full of stupid users like me who do incredibly stupid things. Are you equipped and willing do everything necessary to protect idiots like me from myself? That's a key part of the promise of OpenID, and one of the reasons we chose it as the authentication system for Stack Overflow. As one commenter noted on Reddit:

I, for one, think that my OpenID provider is more secure than the average guy running a forum.

Exactly. We outsourced our user credential system to people who are much better at it than us (well, depending on which OpenID provider you pick). And also because we didn't think the world needed yet another username and password. You're welcome. I think.

So, what have we learned?

  1. Programmers are the enemy.
  2. Hey .. wait a second, I'm a programmer!
  3. GOTO 1

(Oh, and credit to Malte, the first commenter to correctly identify what the likely password vulnerability was -- less than an hour after the entry was posted!)

Discussion

I Just Logged In As You

I received this anonymous email a few days ago:

I found what one could call a security hole in Stackoverflow. I'm curious enough to go digging around for holes, but too ethical to actually do anything with them. However, I'm afraid that by pointing it out I'll get banned, because a good member doesn't poke around like I just did. I promise I did nothing with what I found out besides confirm the hole.

You may be wondering why I'm e-mailing you personally, rather than team@stackoverflow.com. It'll make sense when I reveal the hole, which is...

I logged in as you.

How? Well, there were two pieces of the puzzle, the password and the openid provider. I had a possible password; today your blog post revealed the openid provider. I logged in, freaked out that it actually worked, then logged out. The only reason I had the password is because your password is totally inadequate for someone running a site like StackOverflow. I don't want to go into any more detail than that, but man - dictionary password!

I've read about the secret "hacker" badge... if you're not going to punish me for my transgression, then I will reveal who I am and I sure wouldn't mind getting it. Still, I can understand if you're upset - I wouldn't want someone else digging up my password. (That's why I send this friendly e-mail instead of hoarding, or worst, selling, the information.)

Please, go change your openid password, before someone less ethical than I finds it.

- A friend of the site

These are the kinds of emails that make your blood run cold. Good thing I haven't made too many enemies. Today, I mean. So far. The day's not over, yet.

Is it true? Did someone just log in as me? I checked the OpenID logs, and sure enough, there was a valid login from an IP address I didn't recognize. He wasn't bluffing. He really did log in as me.

While it's true I probably should have used a more secure password, in my defense:

  1. The particular OpenID account I use is typically for low-value logins like blog comments and so forth. It's not exactly a high security form of identity for the use I have in mind.*
  2. The password was relatively simple, but I wouldn't go so far as to characterize it as a "dictionary password" -- it wasn't quite "password1" or "monkey" or "happiness", or anything like that. It was weak, yes, but dictionary password attacks, like all brute force attacks, are still for dummies.

What's interesting about this, though, is how it happened. I'll reveal that tomorrow, with this one hint: I've talked about this exact sort of vulnerability several times on this very blog.

Until then, take your best guess: how do you think this person discovered my password? I'll highlight the best response tomorrow with the answer.

* Although as a Stack Overflow moderator I have unusual powers and probably should have used an alternate OpenID with more security.

Discussion

Optimizing Your Wallet

If we geeks obsessively optimize what's on our keychain, we'd be remiss if we didn't also obsessively optimize that other item most geeks carry around – our wallet.

My current Tumi wallet was almost 10 years old and starting to show its age. While I never had an enormous Constanza Wallet, I felt I could do better.

I was in the market for a new wallet, but I wanted something… less. In search of an alternative, a coworker turned me on to the superthin All-Ett wallet.

all-ett-wallet

After seeing the All-Ett, I was sold. I ordered one. As promised, the fully populated All-ett was thinner – much thinner! – than my old wallet was empty. Amazing! It's so much more comfortable to sit down with this in my back pocket. I no longer feel motivated to remove my wallet from my back pocket when I sit down. That's important. I don't know about you guys, but I tend to lose my wallet when I leave it lying around various places. Not good.

I only have two minor criticisms:

  • The ultra-thin spinnaker sailcloth they use is a tiny bit "crackly" in use. It's not a problem in practical use, you can't hear yourself sit down, but it is a little disconcerting at first.

  • The orientation of the pockets means the contents tend to fall towards the middle when you open it. It's a little more fiddly than a typical wallet when opening it and fishing items out of it. But given that I tend to open my wallet maybe 3-4 times per day, at most, that's a tradeoff I'm willing to make.

Minus those minor criticisms, I'm very happy with it. Or at least I was, until I discovered the Tyvek Mighty Wallets – which even come in a glorious fake dot matrix printout style! Be still, my beating geek heart! Since the sailcloth of the all-ett proved a bit problematic, I'm thinking the Tyvek might be a better choice, and placing my new wallet order. Plus: digits of π! On a dot matrix print-out! Come on, man!

Update: I'm happy to report that I used my Mighty Wallet for years, and just decided to replace it in April 2013 (and again in June 2017) as it was finally getting a bit beat up. Since then, there's been an explosion of amazing Mighty Wallet styles. I liked my old dot matrix model so much I bought three new ones!

Mighty-wallet-in-flight Mighty-wallet-critical-hit
Mighty-wallet-mix-tape tyvek-mighty-wallet-dot-matrix.jpg

But there are other popular geek wallets, too, that I've either had directly recommended to me or seen people use:

Those are the ones I see recommended most, but there are plenty of alternatives discussed in similar posts on 43folders and 37signals.

On a related note, I've always wished I could carry a pen, but I've never found one small and convenient enough to add to my existing keychain. There's quite a bit of stuff on there already: a LED flashlight, a Leatherman Squirt, and of course my keys. I'm not sure if I want to add a pen to that list. But there's another way: I can carry a pen in my wallet! I found two wallet pens that could work.

The Derringer Wallet Pen is only $8. Unfortunately, it was slightly too large for my old wallet at 4" long. So I had to give it away.

derringer-wallet-pen

The wallet pen is quite a bit more expensive at $40 $70. But it's made of sterling silver, and most importantly, it's only 3" and even thinner. So it's even more portable.

wallet-pen-sterling-silver

The wallet pen, as small as it is, fits perfectly in the "crease" of a typical wallet. It does bulge up a tiny bit in the super thin All-ett (and we'll see how it does in the Tyvek wallet), but it still works.

Why not optimize your wallet? You could end up carrying something that's more comfortable, way thinner, and maybe even have something around to write with, too!

Discussion

Has The Virtualization Future Arrived?

On the eve of the Windows 7 release candidate, Microsoft announced that Windows 7 will include a fully licensed, virtualized copy of Windows XP:

XP Mode consists of the Virtual PC-based virtual environment and a fully licensed copy of Windows XP. It will be made available, for free, to users of Windows 7 Professional, Enterprise, and Ultimate editions via a download from the Microsoft web site. XP Mode works much like today's Virtual PC products, but with one important exception: it does not require you to run the virtual environment as a separate Windows desktop. Instead, as you install applications inside the virtual XP environment, they are published to the host OS, with shortcuts placed in the Start Menu. Users can run Windows XP-based applications alongside Windows 7 applications under a single desktop.

I've been talking about our virtual machine future for years. Shipping a fully licensed, virtualized XP along with some editions of Windows 7 has huge implications for backwards compatibility in the Windows world.

For one thing, Windows XP is ancient. While XP may have been the apple of 2001's eye, in computing dog years, it's basically.. dead. The original system requirements for Windows XP are almost comically low:

  • 233 MHz processor
  • 64 MB of RAM (128 MB recommended)
  • Super VGA (800 x 600) display
  • CD-ROM or DVD drive
  • Keyboard and mouse

It doesn't take much to virtualize an OS as old as Windows XP today. I was able to cram a full Windows XP image into 641 MB of disk space, and depending on what sort of apps you're running, 256 MB of memory is often plenty.

The attraction of virtualizing older operating systems is that it throws off the eternal yoke of backwards compatibility. Instead of bending over backwards to make sure you never break any old APIs, you can build new systems free of the contortions and compromises inherent in guaranteeing that new versions of the operating system never break old applications.

Modern virtualization solutions can make running applications in a virtual machine almost seamless, as in the coherence mode of Parallels, or the unity mode of VMWare. Here's a shot of Internet Explorer 7 running under OS X, for example.

virtualization: coherence / unity

From the user's perspective, it's just another application in a window on their desktop. They don't need to know or care if the application is running in a virtual machine. Substitute Windows 7 for OS X, and you get the idea. Same principle. Virtualization delivers nearly perfect backwards compatibility, because you are running a complete copy of the old operating system alongside the new one.

While the screenshot gallery makes it clear to me that this feature of Windows 7 is not nearly as seamless as I'd like it to be, it's a small but important step forward. The demand for perfect backwards compatibility has held the industry back for too long, and having an officially blessed virtualization solution available in a major operating system release (albeit as a downloadable extra, and only in certain editions) opens the door for innovation. It frees software developers from the crushing weight of their own historical software mistakes.

Discussion

A Modest Proposal for the Copy and Paste School of Code Reuse

Is copying and pasting code dangerous? Should control-c and control-v be treated not as essential programming keyboard shortcuts, but registered weapons?

keyboard: ctrl-c, ctrl-v

(yes, I know that in OS X, the keyboard shortcut for cut and paste uses "crazy Prince symbol key" instead of control, like God intended. Any cognitive dissonance you may be experiencing right now is also intentional.)

Here's my position on copy and paste for programmers:

Copy and paste doesn't create bad code. Bad programmers create bad code.

Or, if you prefer, guns don't kill people, people kill people. Just make sure that source code isn't pointed at me when it goes off. There are always risks. When you copy and paste code, vigilance is required to make sure you (or someone you work with) isn't falling into the trap of copy and paste code duplication:

Undoubtedly the most popular reason for creating a routine is to avoid duplicate code. Similar code in two routines is a warning sign. David Parnas says that if you use copy and paste while you're coding, you're probably committing a design error. Instead of copying code, move it into its own routine. Future modifications will be easier because you will need to modify the code in only one location. The code will be more reliable because you will have only one place in which to be sure that the code is correct.

Some programmers agree with Parnas, going so far as to advocate disabling cut and paste entirely. I think that's rather extreme. I use copy and paste while programming all the time, but never in a way that runs counter to Curly's Law.

But pervasive high-speed internet -- and a whole new generation of hyper-connected young programmers weaned on the web -- has changed the dynamics of programming. Copy and paste is no longer a pejorative term, but a simple observation about how a lot of modern coding gets done, like it or not. This new dynamic was codified into law as Bambrick's 8th Rule of Code Reuse:

It's far easier and much less trouble to find and use a bug-ridden, poorly implemented snippet of code written by a 13 year old blogger on the other side of the world than it is to find and use the equivalent piece of code written by your team leader on the other side of a cubicle partition.

(And I think that the copy and paste school of code reuse is flourishing, and will always flourish, even though it gives very suboptimal results.)

Per Mr. Bambrick, copy and pasted code from the internet is good because:

  • Code stored on blogs, forums, and the web in general is very easy to find.
  • You can inspect the code before you use it.
  • Comments on blogs give some small level of feedback that might improve quality.
  • Pagerank means that you're more likely to find code that might be higher quality.
  • Code that is easy to read and understand will be copied and pasted more, leading to a sort of viral reproductive dominance.
  • The programmer's ego may drive her to only publish code that she believes is of sufficient quality.

But copy and pasted code from the internet is bad because:

  • If the author improves the code, you're not likely to get those benefits.
  • If you improve the code, you're not likely to pass those improvements back to the author.
  • Code may be blindly copied and pasted without understanding what the code actually does.
  • Pagerank doesn't address the quality of the code, or its fitness for your purpose.
  • Code is often 'demo code' and may purposely gloss over important concerns like error handling, sql injection, encoding, security, etc.

Now, if you're copying entire projects or groups of files, you should be inheriting that code from a project that's already under proper source control. That's just basic software engineering (we hope). But the type of code I'm likely to cut and paste isn't entire projects or files. It's probably a code snippet -- an algorithm, a routine, a page of code, or perhaps a handful of functions. There are several established code snippet sharing services:

Source control is great, but it's massive overkill for, say, this little Objective-C animation snippet:

- (void)fadeOutWindow:(NSWindow*)window{
float alpha = 1.0;
[window setAlphaValue:alpha];
[window makeKeyAndOrderFront:self];
for (int x = 0; x < 10; x++) {
alpha -= 0.1;
[window setAlphaValue:alpha];
[NSThread sleepForTimeInterval:0.020];
}
}

To me, the most troubling limitation of copypasta programming is the complete disconnect between the code you've pasted and all the other viral copies of it on the web. It's impossible to locate new versions of the snippet, or fold your features and bugfixes back into the original snippet. Nor can you possibly hope to find all the other nooks and crannies of code all over the world this snippet has crept into.

What I propose is this:

// codesnippet:1c125546-b87c-49ff-8130-a24a3deda659
- (void)fadeOutWindow:(NSWindow*)window{
// code
}
}

Attach a one line comment convention with a new GUID to any code snippet you publish on the web. This ties the snippet of code to its author and any subsequent clones. A trivial search for the code snippet GUID would identify every other copy of the snippet on the web:

http://www.google.com/search?q=1c125546-b87c-49ff-8130-a24a3deda659

I realize that what I'm proposing, as simple as it is, might still be an onerous requirement for copy-paste programmers. They're too busy copying and pasting to bother with silly conventions! Instead, imagine the centralized code snippet sharing services automatically applying a snippet GUID comment to every snippet they share. If they did, this convention could get real traction virtually overnight. And why not? We're just following the fine software engineering tradition of doing the stupidest thing that could possibly work.

No, it isn't a perfect system, by any means. For one thing, variants and improvements of the code would probably need their own snippet GUID, ideally by adding a second line to indicate the parent snippet they were derived from. And what do you do when you combine snippets with your own code, or merge snippets together? But let's not over think it, either. This is a simple, easily implementable improvement over what we have now: utter copy-and-paste code chaos.

Sometimes, small code requires small solutions.

Discussion