[wp-trac] [WordPress Trac] #20276: Tie nonces and cookies to expirable sessions
WordPress Trac
noreply at wordpress.org
Thu May 29 19:09:42 UTC 2014
#20276: Tie nonces and cookies to expirable sessions
-------------------------------------------+------------------
Reporter: ryan | Owner:
Type: task (blessed) | Status: new
Priority: normal | Milestone: 4.0
Component: Security | Version:
Severity: normal | Resolution:
Keywords: has-patch commit dev-feedback | Focuses:
-------------------------------------------+------------------
Changes (by nacin):
* keywords: has-patch commit 3.9-early => has-patch commit dev-feedback
* milestone: Future Release => 4.0
Comment:
[attachment:20276.4.diff] is a refresh of duck_'s work here.
On a multisite network with a massive amount of users (take, for example,
wordpress.com or wordpress.org), usermeta is the largest table in the
system. Sessions churn often and it may be desirable to keep these in a
separate database table. It's actually not as much for the table as much
to get them out of the usermeta cache bucket, which can often get really,
really big.
So, [attachment:20276.5.diff] is an alternate take on how we're managing
session storage. It bundles up everything into a WP_Session_Tokens class
with public methods create_token(), verify_token(), destroy_session(), and
destroy_sessions(). Additionally, it has two methods that can be extended:
get_sessions() and update_sessions(). You can specify an alternate class
using the session_token_manager filter that implements these methods to
push/pull from an alternative data store.
Additionally, the plugin allows for additional data to be stored in a
session. By default, we're just storing key/value pairs which are the
verifier (hash of the token) and its expiration. But the
attach_session_information filter can be used to add additional
information, such as the user agent, IP address, and timestamp when the
session was created. I actually engineered this to work out of the box,
making it so get_sessions() always returns an associative array for each
session but only storing the expiration as the value if additional data
isn't being used.
In terms of API and what someone could actually do with this:
get_sessions() is a public method that could be used to enumerate a user's
sessions, such as what Gmail does. destroy_sessions() is essentially a
"log me out everywhere" feature. destroy_other_sessions() doesn't exist
yet but makes sense as the "log me out everywhere else" feature.
There is not an official way to update a session, but a more complicated
data store can handle that in update_sessions(). Use case would be keeping
a log of future activity on that session, such as new IPs used by it, a
"last seen" time, etc.
Additionally, there's no requirement that an expired session actually be
deleted from the data store. So a separate table could, for example, mark
a session as destroyed or expired but keep it around for a set period of
time for auditing purposes (such as letting someone know someone had
logged in from somewhere else, even if they since logged out). To do this
in core by default for expired sessions would be easy, either with a
filter or by default. For destroyed sessions, we could set "expired" value
to -1 or false (when we're storing only minimal information, of course).
I've attached two plugins. [attachment:more-session-info.php] stores user
agent, IP address, and the timestamp when the session was created in
existing usermeta. [attachment:sessions-table.php] uses a global sessions
table (you'll have to add it on your own). The sessions table class works,
though it's not ready for production, as it lacks persistent caching. Easy
to do.
--
Ticket URL: <https://core.trac.wordpress.org/ticket/20276#comment:17>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list