After investigating an issue resulting in a 403 error when trying to access codeforces as described in this blog: https://codeforces.net/blog/entry/80065
I believe I have found the issue and the solution.
Codeforces uses a "slow aes" decryption function to require users to perform a non-trivial amount of computational work before they can access the site, presumably to protect against malicious users spamming the server. A parameter is given based on the user's IP address and the user must decrypt using this to generate a RCPC token in order to access the site.
Those experiencing the 403 error likely are victims of a bug that causes the last 2 characters (last byte in binary) to be deleted. You can confirm this by checking your RCPC token in your cookies. This token should be 32 characters, but is only 30 if you experience this bug.
The aes javascript implementation is from here: https://codeforces.net/aes.min.js
I believe the issue is with the function "unpadBytesOut". In the image below I am logging the "bytesOut" variable, which stores the final token, before and after this function.
console.log("BEFORE" ,bytesOut.toString(), bytesOut.length);
this.unpadBytesOut(bytesOut);
console.log("AFTER" ,bytesOut.toString(), bytesOut.length);
As you can see, in this particular case, the last byte has been deleted by this function. I have found that around 8% of randomly generated aes parameters (the one based on your ip) has this issue.
If you are having this issue, download the javascript and run it locally, after removing the line calling this function. I am also happy to generate the token for anyone who has difficulty doing it themselves. If you send me your response from codeforces.com without redirects and I can send you the corrected token. If you're on linux or max for example, you can send me the response to the command "curl codeforces.com". Note that this token won't compromise the security of your account as I believe it is purely to protect again a DDOS by verifying the IPs.
I hope MikeMirzayanov can get this fixed as soon as possible.
UPD: I believe the issue has now been resolved. The aes.min.js has been updated with an additional conditional in the previously broken unpadBytesOut function. Below is a diff of the new change: