WordPress.org

Make WordPress Core

Opened 15 months ago

Closed 15 months ago

Last modified 15 months ago

#43576 closed enhancement (wontfix)

Do not expose user_login through cookies

Reported by: marcus.downing Owned by:
Milestone: Priority: normal
Severity: normal Version: 5.1
Component: Login and Registration Keywords:
Focuses: Cc:

Description

An ITHC recently reported that the cookies wordpress_logged_in and wordpress_sec contain the current username. This exposes the possibility that user's username can be extracted by a third party that is able to read the cookie.

Of course the cookies themselves should be and are protected in other ways (including HttpOnly and Secure), and an attacker who has managed to intercept a session cookie already has the means to log in as you; but if the security issues seen in recent years (to all software, not just WordPress) have taught us anything it's that if you take security serious you need to close all the doors, not just one of them.

I understand that some may regard this as a non-issue, but since it was raised to us during a security review we're obliged to take it seriously.

Proposed solution

On user login, a unique value is created and saved in usermeta. This value should be different each time you log in, and reveal nothing about the user or their ID. The value is sent with the cookie in place of the username. Multiple such records can and will coexist, representing the user logging in from multiple devices.

On cookie verification, the value is retrieved from usermeta and used to find the user ID.

This solution has the added benefit that it will be harder for an attacker to fake a WordPress login cookie even if they have your database and salts, since any session they created would not be in the database. On the other hand it has a side effect that losing the current user login entries from usermeta (such as by reverting to backup database) would invalidate login sessions.

As a downside it would involve a reasonably high turnover of temporary records in the usermeta table; it may be preferable to use transient entries in the options table instead.

An alternative solution would be to reversibly encrypt the username part of the cookie, and decrypt it on verification.

Affected code

In wp-includes/pluggable.php, the functions:
wp_generate_auth_cookie($user_id, $expiration, $scheme, $token)
wp_validate_auth_cookie($cookie, $scheme).

Note that the pluggable nature of these functions means I can (and probably will) write a plugin to address the issue on my own site. However, I believe this change may benefit security for others and should therefore be addressed in core.

Possibly related

#9577 use user_id rather than user_login in the authentication cookie

This was discussed in a different context and rejected 9 years ago, but the issue isn't the same, and I believe we've all learned more about security in the last 9 years.

In particular, this issue suggested using the user's ID rather than their username. This provided little or no security benefit, because there are various ways of getting a user's login from their ID. My suggestion above instead uses a temporary code that reveals nothing and is hard to fake.

Change History (3)

#1 @marcus.downing
15 months ago

Note that the documentation (https://codex.wordpress.org/WordPress_Cookies#Non-Version-Specific_Data) says:

The actual cookies contain hashed data, so you don't have to worry about someone gleaning your username and password by reading the cookie data.

This is currently incorrect, as the username is in the cookie. If this issue is rejected, then the documentation should be changed.

#2 @peterwilsoncc
15 months ago

  • Milestone Awaiting Review deleted
  • Resolution set to wontfix
  • Status changed from new to closed

As has been discussed in other tickets, the WordPress project doesn't consider usernames or user ids to be private or secure information. A username is part of your online identity. It is meant to identify, not verify, who you are saying you are. Verification is the job of the password.

Many major online establishments — such as Google and Facebook — have done away with usernames in favor of email addresses, which are shared around constantly and freely. WordPress has also moved this way, allowing users to log in with an email address or username since version 4.5.

The text you refer to the documentation for login cookies is referring to gleaning both the username and password. Granted, the text could do with a minor edit to make this clearer.

For additional protection of logins, you can also consider the two factor authentication plugin.

I'm going to close this ticket as wontfix as username exposure has been discussed in several related tickets: #3708, #5301, #5388, #14644, #20235.

#3 @johnbillion
15 months ago

The Codex page that @marcus.downing mentioned above is incorrect in this regard. Who wants to correct it?

Note: See TracTickets for help on using tickets.