It appears that calling Url.IsLocalUrl(returnUrl) is producing different results given what seems to be the same value for returnUrl. How is this possible?
MVC app targeting framework 4.7.1. In trying to prevent open redirection attacks, I have the code below. Pretty simple and generic.
When I try to go to our landing page without being logged in and I'm redirected back to our login page, my URL is: https://ourdomain.com/I/Login?ReturnUrl=%2fI%2fHome. When I login, the URL I find myself at is: https://ourdomain.com/I/Home. Perfect. As expected. This works for 99.9+% of our users, else we'd be getting flooded with errors, and we're not.
However, we have at least one user that is getting an error here. Our error logs say: "An open redirection attack was detected. User was going to login and then be returned to: %2fI%2fHome."
My working returnUrl and the one in our error logs are the exact same, and it works 99.9+% of the time for the same value. I'm unable to reproduce the error myself. Why would this produce different results on rare occasions? Thanks in advance for any suggestions!
if (!string.IsNullOrWhiteSpace(returnUrl) && !Url.IsLocalUrl(returnUrl))
{
throw new Exception($"An open redirection attack was detected. User was going to login and then be returned to: {returnUrl}.");
}