[wp-trac] [WordPress Trac] #43141: wp_nonce_url() in combination with sprintf %s

WordPress Trac noreply at wordpress.org
Sun Jan 21 21:37:38 UTC 2018


#43141: wp_nonce_url() in combination with sprintf %s
--------------------------+----------------------
 Reporter:  qvarting      |       Owner:
     Type:  defect (bug)  |      Status:  closed
 Priority:  normal        |   Milestone:
Component:  Formatting    |     Version:  4.9.2
 Severity:  normal        |  Resolution:  invalid
 Keywords:                |     Focuses:
--------------------------+----------------------
Changes (by johnbillion):

 * status:  new => closed
 * resolution:   => invalid
 * milestone:  Awaiting Review =>


Comment:

 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 the
 `wp_nonce_url()` function, which means it's not properly protected.)

 The `%s` value for your `action` parameter is being passed through
 `wp_nonce_url()`, which in turn passes it through `add_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 your
 `action` parameter becomes `%25s`. This gets treated by `sprintf()` 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.

 {{{
 $action = ( $enabled ) ? 'action_disable' : 'action_enable';
 $url = add_query_arg( array(
         'action'  => $action,
         'item_id' => 123,
 ), admin_url( 'admin-post.php' ) );
 $url = wp_nonce_url( $url, $action );

 echo sprintf(
         '<a href="%s">%s</a>',
         esc_url( $url ),
         ( $enabled ) ? 'Disable item' : 'Enable item'
 );
 }}}

--
Ticket URL: <https://core.trac.wordpress.org/ticket/43141#comment:1>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform


More information about the wp-trac mailing list