Invalid download links due to query string order modification
Easy Digital Downloads has a robust system in place to keep your file download links secure and prevent them from being abused. When a file download link is clicked, the order of the parameters provided is important. From time to time, certain hosting configurations, caching layers, or CDN providers may re-order the query string parameters in order to allow some base level caching to be done. Re-ordering these items will cause Easy Digital Downloads to fail the token validation for a customer’s download link.
How can I tell if this is my issue?
If, when a user clicks to download their files, they are given the error “You do not have permission to download this file”, check that the URL still has the following format, paying close attention to the order of the parameters.
http://example.org/index.php?eddfile=...&ttl=...&file=...&token=...
If the query string parameters are not in the above order, then you are experiencing the issue described above. We do have a few solutions to help prevent this from occurring.
If you have an page caching system setup, like Cloudflare or Varnish, then you may still see this error even though your parameters appear to be in the correct order. This is due to the page caching system sorting those parameters before sending your request to the webserver to be processed by PHP.
How can I prevent this issue?
Hosting configuration changes
The ideal situation is to not have your providers re-order the query string parameters when the request is for a file download by preventing any request containing the eddfile query string parameter from being passed through the re-ordering rules.
If you are using Cloudflare and have enabled their Query String Sort feature, you should be able to disable this feature to allow users to download their files without error.
Custom code snippet
We recognize that this may not always be possible with some providers, so we’ve written a small function that will run any failed validation a 2nd time, to verify that we received the items in the proper order.
function ck_custom_validate_url_token( $ret, $url, $query_args ) { // If basic validation failed, let's make sure the URL prarms were in the right order and try again if ( false === $ret ) { $parts = parse_url( $url ); wp_parse_str( $parts['query'], $query_args ); $fix_arg_order = array( 'eddfile' => $query_args['eddfile'], 'ttl' => $query_args['ttl'], 'file' => $query_args['file'], 'token' => $query_args['token'], ); $fixed_url = add_query_arg( $fix_arg_order, site_url() ); $fixed_token = edd_get_download_token( $fixed_url ); $ret = $query_args['token'] === $fixed_token; } return $ret; } add_filter( 'edd_validate_url_token', 'ck_custom_validate_url_token', 10, 3 );
The above function should be tested in a staging environment prior to using it on a production environment, to verify it works correctly in your specific configuration.