Skip to content

Commit a1735b0

Browse files
swissspidyclaude
andauthored
Avoid leaving persistent session tokens behind in admin context (#6436)
The admin context called wp_generate_auth_cookie() twice without a token, which made core create and store two new sessions for the admin user on every command run in that context (e.g. every `wp plugin` or `wp theme` command since auto context became the default). Create a single session token, share it between both auth cookies and destroy it again on shutdown. Fixes wp-cli/extension-command#562 Claude-Session: https://claude.ai/code/session_014pxdff1vWQ6SQ3XbhPZrij Co-authored-by: Claude <noreply@anthropic.com>
1 parent 2278cf3 commit a1735b0

2 files changed

Lines changed: 37 additions & 2 deletions

File tree

‎features/context.feature‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,3 +350,21 @@ Feature: Context handling via --context global flag
350350
"""
351351
Error: Invalid user ID, email or login: 'non_existent_user'
352352
"""
353+
354+
Scenario: Admin context does not leave persistent session tokens behind
355+
Given a WP install
356+
357+
When I run `wp --context=admin eval "echo count( WP_Session_Tokens::get_instance( 1 )->get_all() ) . ' ' . ( wp_validate_auth_cookie( \$_COOKIE[ AUTH_COOKIE ], 'auth' ) ?: 'invalid' );"`
358+
Then STDOUT should be:
359+
"""
360+
1 1
361+
"""
362+
363+
When I run `wp plugin list`
364+
And I run `wp theme list`
365+
And I run `wp --context=admin eval ''`
366+
And I run `wp eval "echo count( WP_Session_Tokens::get_instance( 1 )->get_all() );"`
367+
Then STDOUT should be:
368+
"""
369+
0
370+
"""

‎php/WP_CLI/Context/Admin.php‎

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use WP_CLI;
66
use WP_CLI\Context;
77
use WP_CLI\Fetchers\User;
8+
use WP_Session_Tokens;
89
use WP_User;
910

1011
/**
@@ -141,6 +142,10 @@ private function get_fake_admin_page(): string {
141142
* A lot of premium plugins/themes have their custom update routines locked
142143
* behind an is_admin() call.
143144
*
145+
* A single session token is shared by both auth cookies and destroyed
146+
* again on shutdown, so that running commands in the admin context does
147+
* not leave stale sessions behind for the admin user.
148+
*
144149
* @param int<1, max> $admin_user_id to log in as
145150
*
146151
* @return void
@@ -150,16 +155,28 @@ private function log_in_as_admin_user( $admin_user_id ): void {
150155

151156
$expiration = time() + DAY_IN_SECONDS;
152157

158+
$manager = WP_Session_Tokens::get_instance( $admin_user_id );
159+
$token = $manager->create( $expiration );
160+
161+
WP_CLI::add_wp_hook(
162+
'shutdown',
163+
static function () use ( $manager, $token ) {
164+
$manager->destroy( $token );
165+
}
166+
);
167+
153168
$_COOKIE[ AUTH_COOKIE ] = wp_generate_auth_cookie(
154169
$admin_user_id,
155170
$expiration,
156-
'auth'
171+
'auth',
172+
$token
157173
);
158174

159175
$_COOKIE[ SECURE_AUTH_COOKIE ] = wp_generate_auth_cookie(
160176
$admin_user_id,
161177
$expiration,
162-
'secure_auth'
178+
'secure_auth',
179+
$token
163180
);
164181
}
165182

0 commit comments

Comments
 (0)