Encode values passed to `add_query_arg`
VIP recommends checking the WordPress Codex when using an unfamiliar or less frequently used function. The usage description and user-supplied notes can help show “gotchas”, identify possible unexpected results, or clarify whether the function returns output-safe results or if further escaping is needed.
For example, the description for add_query_arg()
includes an important reminder:
Values are expected to be encoded appropriately with
urlencode()
orrawurlencode()
.
In the following code, imagine that a value from user input or a global input var contains a complex string:
$my_url = 'admin.php?action=delete&post_id=321';
$my_url = add_query_arg( 'my_arg', 'somevalue&post_id=123', $my_url );
You may expect the resulting URL to be admin.php?action=delete&post_id=123&my_arg=somevalue%26post_id%3D123
But, without encoding the value, the result is admin.php?action=delete&post_id=321&my_arg=somevalue&post_id=123
The URL has now been hijacked, and if used, post 123 would be deleted instead of 321.
To protect against accidental or intentional exploits, use rawurlencode()
as the Developer Resource page recommends, so that somevalue&post_id=123
is safely encoded into somevalue%26post_id%3D123
, protecting the intent of the URL.
This can be equally troublesome when attempting to intentionally pass a set of arguments to a URL, such as a redirect after an action.
You can either convert every single argument:
add_query_arg( 'my_arg', rawurlencode( 'somevalue&post_id=123' ), $myurl );
Or update all the arguments at once:
$args = array(
'my_arg' => 'somevalue&post_id=123',
'my_second_arg' => $my_second_arg,
);
$args = array_map( 'rawurlencode', $args );
$my_url = add_query_arg( $args, $my_url);
Using rawurlencode
on any variable used as part of the query string, either by using add_query_arg()
or directly by string concatenation, will prevent parameter hijacking.
Last updated: September 18, 2024