pegasus
Well-known member
- Affected version
- 2.2.8
When we set a custom privacy policy or terms URL, we expect \XF\Pub\Controller\AbstractController::canBypassPolicyAcceptance handles this automatically. In fact, at first glance, it looks like it will. However, when clicking the link to open the custom policy (as any user wanting to read the policy before accepting it), XenForo just redirects back to the acceptance form. Even if I explicitly list the routePath in the appropriate whitelist, XenForo just redirects back to the acceptance form. The problem is in the following logic:
Here, you see that the whitelist goes through each entry, including the custom policy URL, and makes sure it ends with a trailing /
However, then we compare the current routePath, without also ensuring that it ends with a trailing /
So when the actual custom URL actually doesn't end in a trailing /, then this rule never matches.
There are several ways to fix this issue:
- Exempt the custom policy URL from the array_map that adds a trailing / (not ideal, since other whitelist entries could potentially share this problem too):
OR
- Only add a trailing / if one was removed by rtrim (* probably best):
OR
- Add a trailing / to the $requestRoutePath before comparing:
For the time being I have implemented the last option as a fix on my site.
Code:
$whitelistRoutePaths[] = $request->getRoutePathFromUrl($policyUrl);
$whitelistRoutePaths = array_map(function($routePath)
{
return rtrim($routePath, '/') . '/';
}, $whitelistRoutePaths);
$requestRoutePath = $request->getRoutePathFromUrl($requestUri);
return in_array($requestRoutePath, $whitelistRoutePaths, true);
However, then we compare the current routePath, without also ensuring that it ends with a trailing /
So when the actual custom URL actually doesn't end in a trailing /, then this rule never matches.
There are several ways to fix this issue:
- Exempt the custom policy URL from the array_map that adds a trailing / (not ideal, since other whitelist entries could potentially share this problem too):
Code:
$whitelistRoutePaths = array_map(function($routePath)
{
return rtrim($routePath, '/') . '/';
}, $whitelistRoutePaths);
$whitelistRoutePaths[] = $request->getRoutePathFromUrl($policyUrl);
- Only add a trailing / if one was removed by rtrim (* probably best):
Code:
$newPath = rtrim($routePath, '/');
if (substr($newPath, -1) != substr($routePath, -1))
{
$newPath .= '/';
}
return $newPath;
- Add a trailing / to the $requestRoutePath before comparing:
Code:
$requestRoutePath = rtrim($request->getRoutePathFromUrl($requestUri), '/') . '/';