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
But in fact, without encoding the value, the result is
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);
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