Make WordPress Core

Opened 6 years ago

Last modified 7 weeks ago

#52378 accepted defect (bug)

Network admin site action confirmation leads to expired link screen when referer not available

Reported by: sanchothefat Owned by: realloc
Priority: normal Milestone: Awaiting Review
Component: Networks and Sites Version:
Severity: normal Keywords:
Cc: Focuses: multisite

Description

Sorry for the wordy summary.

In the network admin on a multisite installation the sites list shows links for actions like "Archive", "Deactivate" etc. that take you to an interstitial page to confirm the action.

This interstitial page outputs a simple form with the action being confirmed, nonce values and so on filled in, including a field for _wp_http_referer which is then used in the check_admin_referer() call.

The referrer field is built using the following code:

<?php
<input type="hidden" name="_wp_http_referer" value="<?php echo esc_attr( wp_get_referer() ); ?>" />

In infrastructure where WordPress is behind a load balancer and for caching reasons the referer header is not passed to the web server this breaks because the output from wp_get_referer() is empty. Clicking confirm will result in a wp_die() screen from wp_nonce_ays() saying the link has expired.

This can be worked around by filtering network_admin_url where the link contains action=confirm to add _wp_http_referer as a query parameter but ideally the referer should be passed in the query string by default.

Given there is a workaround this is low priority, and I can't see anywhere else in WP affected by this currently either.

Change History (3)

#1 @johnbillion
6 years ago

  • Component GeneralNetworks and Sites
  • Focuses multisite added

#2 @sanchothefat
6 years ago

I found another related issue with the "Network Enable" and "Network Disable" action links for themes in the network admin too. If the referrer header is missing they cause an infinite redirect loop also. These links are generated using wp_nonce_url() which is not filterable so the workaround using the network_admin_url filter is not an option.

#3 @realloc
7 weeks ago

  • Owner set to realloc
  • Status newaccepted

Confirmed on current trunk; both the original report and Comment 2 are still reproducible, and they share one root cause. After the action runs, the post-action redirect passes wp_get_referer() into add_query_arg()/remove_query_arg(). When the Referer header is stripped, wp_get_referer() returns false, which those functions silently resolve to the current request URI (the action URL itself).

I believe it is fixable together by treating an empty/false referer as "no referer" and falling back to a safe default instead of the current request URI.

Note: See TracTickets for help on using tickets.