Skip to content

fix: correct the nonce argument in the version switch AJAX handlers - #494

Closed
TallblokeUK wants to merge 1 commit into
core-betafrom
fix/version-switch-nonce/core
Closed

fix: correct the nonce argument in the version switch AJAX handlers#494
TallblokeUK wants to merge 1 commit into
core-betafrom
fix/version-switch-nonce/core

Conversation

@TallblokeUK

Copy link
Copy Markdown
Contributor

Switching or rolling back the plugin version does nothing. Picking a version and clicking Switch Version shows "An error occurred."; Refresh Available Versions resets its own label without any message at all. Reproduced on a live site as well as locally.

check_ajax_referer( $action, $query_arg ) treats $query_arg as the name of the request key to read the nonce from. Both handlers passed the nonce's value there instead, so WordPress looked for $_REQUEST['<the nonce value>'], fell through to _ajax_nonce and _wpnonce — neither of which the front end sends — and verified an empty string. Every request was rejected, valid nonce or not.

Promotion_Base::dismiss_promotion_ajax_handler() already does this correctly with check_ajax_referer( self::AJAX_ACTION, 'nonce' ), which is the form used here.

Testing

Against admin-ajax.php as a logged-in admin:

before after
refresh, valid nonce 403 200 success
refresh, invalid nonce 403 403
switch, valid nonce 403 reaches the handler
switch, invalid nonce 403 403

The switch case was exercised with an empty target_version, so the request passes the nonce and capability checks and stops at validation — proving the gate opens without installing anything.

Driven through the real UI afterwards: the dropdown populates with all 62 versions from wordpress.org and both buttons respond. phpcs clean.

Note this sits behind Settings → Debug → Enable version change, which is off by default, so only people who switched it on will have hit it.

check_ajax_referer() reads its second argument as the name of the request
key holding the nonce, but both handlers passed the nonce value itself.
WordPress looked for $_REQUEST['<nonce value>'], found nothing, fell
through to _ajax_nonce and _wpnonce which the front end does not send,
and ended up verifying an empty string.

Both handlers therefore rejected every request with a 403, including
requests carrying a valid nonce, so Switch Version and Refresh Available
Versions did nothing. Passing the key name lets a valid nonce through
while an invalid one is still rejected.
@TallblokeUK

Copy link
Copy Markdown
Contributor Author

Superseded by #506, which targets release/v3.10.2/core so it can ship in 3.10.2. Same commit, cherry-picked onto the release branch; retargeting this one directly would have pulled in unrelated core-beta changes to the test files.

@TallblokeUK TallblokeUK closed this Sep 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant