don’t forget to secure cookies ppl

Update (5/28/14): Regrettably, most of the stories covering this blog post have been all “OMG EVERYTHING IS BROKEN” rather than “Here’s how to make things better til WordPress rolls out a fix” (which I humbly believe will take a while to *fully* fix, given that their SSL support is so patchy). So, given that most people reading this are probably coming from one of those articles, I think it’s important to start with the actionable items that people can do to mitigate cookie-hijacking attacks on WordPress:

  1. If you’re a developer running your own WordPress install, make sure you set up SSL on all relevant servers and configure WordPress to auth flag cookies as “secure.”
  2. If you’re a WordPress user, don’t be logged into WordPress on an untrusted network, or use a VPN. If you are and you visit a wordpress.com site (which confusingly may not actually have a wordpress.com domain name), your auth cookies are exposed.
  3. [Experimental, probably not recommended] You can manually set the “secure” flag on the WP auth cookies in your browser. There’s no guarantee that this works consistently, since the server can always send a set-cookie that reverts it into an insecure cookie. It may cause some WP functionality to break.
  4. If you suspect that your WP cookie may have been stolen in the past, you can invalidate it by (1) waiting 3 years for it to expire on the server or (2) resetting your wordpress.com password. Note that logging out of WordPress does *not* invalidate the cookie on the server, so someone who stole it can use it even after you’ve logged out. I verified that resetting your WP password does invalidate the old cookie; there may be other ways, but I haven’t found any.

Original post below.

 

While hunting down a bug report for Privacy Badger, I noticed the “wordpress_logged_in” cookie being sent over clear HTTP to a WordPress authentication endpoint (http://r-login.wordpress.com/remote-login.php) on someone’s blog.

uh-oh

uh-oh

Sounds like bad news! As mom always said, you should set the “secure” flag on sensitive cookies so that they’re never sent in plaintext.

To check whether this cookie did anything interesting, I logged out of my wordpress account, copied the wordpress_logged_in cookie into a fresh browser profile, and visited http://wordpress.com in the new browser profile. Yep, I was logged in!

This wouldn’t be so bad if the wordpress_logged_in cookie were invalidated when the original user logged out or logged back in, but it definitely still worked. Does it expire? In 3 years. (Not sure when it gets invalidated on the server side, haven’t waited long enough to know.)

Is this as bad as sending username/password in plaintext? I tried to see if I could reset the original user’s password.

wordpresspassword1

That didn’t work, so I’m assuming WordPress uses the actually-secure cookie (wordpress_sec) for super important operations like password change. Nice job, but . . .

It turns out I could post to the original user’s blog (and create new blog sites on their behalf):

wordpress_postblog

I could see private posts:

wordpress_postsecretblog

I could post comments on other blogs as them:

wordpress_postcomment

I could see their blog stats:

wordpress_stats

And so forth. I couldn’t do some blog administrator tasks that required logging in again with the username/password, but still, not bad for a single cookie.

Moral of the story: don’t visit a WordPress site while logged into your account on an untrusted local network.

Update: Thanks to Andrew Nacin of WordPress for informing me that auth cookies will be invalidated after a session ends in the next WordPress release and that SSL support on WordPress will be improving!

Update (5/26/14): I subsequently found that the insecure cookie could be used to set someone’s 2fac auth device if they hadn’t set it, thereby locking them out of their account. If someone has set up 2fac already, the attacker can still bypass login auth by cookie stealing – the 2fac auth cookie is also sent over plaintext.

Update (5/26/14): A couple people have asked about whether the disclosure timeline below is reasonable, and my response is here.

Disclosure timeline:

Wed, 21 May 2014 16:12:17 PST: Reported issue to security@automattic.com, per the instructions at http://make.wordpress.org/core/handbook/reporting-security-vulnerabilities/#where-do-i-report-security-issues; at this point, the report was mostly out of courtesy, since I figured it had to be obvious to them and many WP users already that the login cookie wasn’t secured (it’s just a simple config setting in WordPress to turn on the secure cookie flag, as I understand it). Received no indication that the email was received.

22 May 2014 16:43: Mentioned the lack of cookie securing publicly. https://twitter.com/bcrypt/status/469624500850802688

22 May 2014 17:39: Received response from Andrew Nacin (not regarding lack of cookie securing but rather that the auth cookie lifetime will soon be that of a regular session cookie). https://twitter.com/nacin/status/469638591614693376

23 May 2014 ~13:00: Discovered two-factor auth issue on accident, reported to both security@automattic.com and security@wordpress.org in reply to original email. I also mentioned it to Dan Goodin since I found the bug while trying to answer a question he had about cookies, but I did not disclose publicly.

25 May 2014 15:20: Received email response from security@automattic.com saying that they were looking into it internally (no mention of timeline). Wrote back to say thanks.

26 May 2014, ~10:00: Ars Technica article about this gets published, which mentioned the 2-fac auth issue. I updated this blog post to reflect that.

26-27 May 2014: Some commenters on the Ars Technica article discover an arguably worse bug than the one that the original article was about: WordPress sends the login form over HTTP. (Even though the form POST is over HTTPS, the local network attacker can modify the target on the HTTP page however he/she wants and then it’s game over.) This wouldn’t be so bad if everyone used a password manager and changed passwords semi-regularly, since most people are likely to login to WordPress through their blog’s admin portal (which is always HTTPS as far as I can tell), except that password reuse is rampant. Robert Graham subsequently published this blog post.

29 May 2014, 5:52: Received reply from WordPress saying they would email me again when fixed.

30 May 2014, 14:51: Andrew Nacin says all issues are supposedly fixed.