The problem:
When my website is set to "I'm under attack" mode, once a user passes the CloudFlare screen they are redirected to my website with a large, and rather long query get parameter:
?__cf_chl_jschl_tk__=63c51316f61a63e46f1639d6cf43f9d9b536adea-1587754610-0-AV-peahelegQeMeSrc_4ZJBUq47gdkX_QiS2eERoRTEODUjwbib2MM_73nQDAhukLbkspNpj01mv-Z-JteR4MpY4LUMm-yLJrPQKTX74DGYbZIs2utbp3_q4uozgzKpqcax10YESVKDhZgaWQYHGqBL9koIoasVOzKyvU7VQuKT1Nieo-i8DdXrV0IQf-nyI8KgWnxhYSVBOc-4WNrZzHQlEXFOpV45AGs10aMJyrs376HLRhNdV05MCj8oqMrexuQDtY7B3p7riHByYdB7GIgc
Why this is bad:
Proposed solution:
The way I see to avoid this would be to check if the get parameters are set and then redirect back to the same page with the parameters removed. (Making sure not to lose any other query parameters if set)
I have written a function to achieve this:
function checkAndRemoveCloudFlareParams() {
if (isset($_GET['__cf_chl_jschl_tk__']) && ! empty($_GET['__cf_chl_jschl_tk__'])
|| isset($_GET['__cf_chl_captcha_tk__']) && ! empty($_GET['__cf_chl_captcha_tk__'])) {
$new_uri = '?';
$uri = explode('?', $_SERVER['REQUEST_URI']);
$uri = $uri[0];
// Get any other params to put back on later
foreach ($_GET as $key => $var) {
if ($key !== '__cf_chl_jschl_tk__' && $key !== '__cf_chl_captcha_tk__') {
$new_uri .= $key . '=' . $var . '&';
}
}
if ($new_uri !== '?') {
$new_uri = rtrim($new_uri, '&');
$uri .= $new_uri;
}
header('Location: ' . $uri);
die;
}
}
When I test this locally by manually entering the _GET parameters it works. However when deployed up to my live site, the _GET query parameters are not there or available to access when loaded directly from CloudFlare. I believe CloudFlare adds the parameters after the page has been loaded? Maybe through Javascript push states(?) Has anyone else dealt with this before?
I have spoken to CloudFlare about this already and they said this is how it will work from now on as there were problems with their old system. Unfortunately these query parameters are very ugly and are making me start to twitch from annoyance of seeing it all the time ;)
Any advice on how to deal with these params and get rid of them? Kind regards
JS solution:
(function(){
var reg = /[\?&](__cf_chl_jschl_tk__|__cf_chl_captcha_tk__|__cf_chl_managed_tk__|__cf_chl_tk)=[^&]+/
history.replaceState && reg.test(location.search) && history.replaceState(
null, '', location.pathname + location.search.replace(reg, '').replace(/^&/, '?') + location.hash
);
})();
Updated in 2022 to deal with What exactly is the `#:~:text=` location hash in an URL? because it is not present in location.hash
Cloudflare is a distributed reverse proxy. All your requests and responses are transmitted through the Cloudflare's reverse proxy in cleartext. The __cf_chl_jschl_tk__
(Cloudflare challenge / Javascript challenge token) is added to the redirect location URLs at the proxy and would be stripped at the proxy before it gets to your website.
You may try to get rid of the token with Javascript, however, it's important to understand the consequences. If a token is missing in a request, Cloudflare would be more likely to run your users through anti-bot challenges again and again, leading to poor user experience.
How exactly likely it would be to do that remains a mystery though, because DDoS mitigation services do not typically openly document those details.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With