#43141 closed defect (bug) (invalid)
wp_nonce_url() in combination with sprintf %s
Reported by: |
|
Owned by: | |
---|---|---|---|
Milestone: | Priority: | normal | |
Severity: | normal | Version: | 4.9.2 |
Component: | Formatting | Keywords: | |
Focuses: | Cc: |
Description
Hi,
The following code does not output the correct data:
<?php echo sprintf( '<a href="' . esc_url( wp_nonce_url( admin_url('admin-post.php') . '?action=%s&item_id=123' ) ) . '">%s</a>', $enabled ? 'action_disable' : 'action_enable', $enabled ? 'Disable item' : 'Enable item' );
Result:
/wp-admin/admin-post.php?action=%20%20%20%20%20%20%20%20%20%20%20action_disable&item_id=123&_wpnonce=05bd1b0af4
Note all spaces after action=
Cheers
Change History (2)
Note: See
TracTickets for help on using
tickets.
Thanks for the report @qvarting, and welcome to WordPress Trac.
This is a problem caused by the order in which you're constructing your URL. (In addition, you're not passing a valid
action
parameter to thewp_nonce_url()
function, which means it's not properly protected.)The
%s
value for youraction
parameter is being passed throughwp_nonce_url()
, which in turn passes it throughadd_query_arg()
. Inside this function, query variables get URL-encoded so they are correctly displayed. A percent%
symbol is not valid in a query variable as-is, so it gets URL-encoded as%25
. This means the value for youraction
parameter becomes%25s
. This gets treated bysprintf()
as a right-justified string with length of 25. Hence, you get 12 spaces prepended to the value as padding.The correct way to construct the URL is to perform your placeholder replacement before passing it through any function which deals with reformatting the URL. A query variable containing a non-encoded
%
symbol will get URL-encoded if you pass it through various functions in WordPress or PHP.