Skip to content

Backgrounds

How-to Guides

Technical References

Code Quality and Best Practices /

Encode values passed to add_query_arg

Generally, a quick check of the Codex is well worth the time when using a function that may be unfamiliar, or if it’s been a while since it was last used. Both the usage description and the user-supplied notes can be helpful in showing gotchas or identifying if the function may sometimes return an unexpected result. It also helps clarify whether the function returns output-safe results or further escaping is needed.

Add_query_arg() is one example, because in the middle of the description is an important reminder:

Values are expected to be encoded appropriately with urlencode() or rawurlencode().

For example, in the following code, a value (imagine it came 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 in fact, 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 exploit, 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 pass a set of arguments to a URL intentionally, 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: April 09, 2021