Confirmed Apple Connected Account (no valid request available)

mjda

Well-known member
Licensed customer
Affected version
2.3.6
On all my sites when I try to log in via Apple connected account, I receive the following error:

There is no valid connected account request available. Please try again.

This happens on login, or when testing the connected account via the ACP.

I get the same error trying to connect my Apple account right here on XenForo.com.
 
I don't mean to seem impatient but can someone create a patch for this bug, or has someone already created a patch they'd be willing to share? I'm paying $100/year for the Apple Developer Program and I'm basically just throwing that money away at this point because of this bug.

On a side note, does anyone know if I let my Apple Developer Program membership lapse, then re-purchase it if/when this bug is fixed, would I have to completely re-do the implementation for every site or would all my details still be there?
 
The OAuth response returned from Apple is via a cross-site POST (response_mode=form_post). XenForo sets no SameSite attribute on its session cookies, so browsers treat them as SameSite=Lax by default (Lax cookies are withheld on cross-site POSTs (at least for chromium browsers like Chrome and Edge)). In this case, the browser can't tell Apple's POST apart from a malicious CSRF attempt. The xf_session cookie never reaches connected_account.php; XenForo sees the request as an anonymous session with no pending connect request and therefore we get the "There is no valid connected account request available."

I was able to reproduce this on my board as well and here are my two workarounds:
1) Modify the src/config.php file to set the SameSite config to None (e.g. $config['cookie']['samesite'] = 'None';)
2) Capture the request and reissue it as a GET request.

Option #1 feels wrong, arguably decreasing the overall security posture of the site just for Apple.
Option #2 is hacky, but you can get things working by adding the following to connected_account.php. The code takes the POST request and turns it into a GET request back to itself (via 303 redirect), so the browser can send the session cookie back and complete the auth flow. Just note the change is lost on XenForo upgrade.

Search for:
$connectedAccountRequest = $session->get('connectedAccountRequest');

Add this below it:
PHP:
if ($request->isPost() && !$connectedAccountRequest)
{
    $code = (string) $request->filter('code', 'str');
    $error = (string) $request->filter('error', 'str');

    if ($code !== '' || $error !== '')
    {
        $params = [];
        foreach (['code', 'state', 'error', 'error_description', 'denied'] AS $bounceKey)
        {
            $bounceValue = (string) $request->filter($bounceKey, 'str');
            if ($bounceValue !== '')
            {
                $params[$bounceKey] = $bounceValue;
            }
        }

        $bounceUrl = $app->options()->boardUrl . '/connected_account.php';
        if ($params)
        {
            $bounceUrl .= '?' . http_build_query($params);
        }

        $response->header('Referrer-Policy', 'no-referrer');
        $response->redirect($bounceUrl, 303);
        $response->send($request);

        exit;
    }
}
 
The OAuth response returned from Apple is via a cross-site POST (response_mode=form_post). XenForo sets no SameSite attribute on its session cookies, so browsers treat them as SameSite=Lax by default (Lax cookies are withheld on cross-site POSTs (at least for chromium browsers like Chrome and Edge)). In this case, the browser can't tell Apple's POST apart from a malicious CSRF attempt. The xf_session cookie never reaches connected_account.php; XenForo sees the request as an anonymous session with no pending connect request and therefore we get the "There is no valid connected account request available."

I was able to reproduce this on my board as well and here are my two workarounds:
1) Modify the src/config.php file to set the SameSite config to None (e.g. $config['cookie']['samesite'] = 'None';)
2) Capture the request and reissue it as a GET request.

Option #1 feels wrong, arguably decreasing the overall security posture of the site just for Apple.
Option #2 is hacky, but you can get things working by adding the following to connected_account.php. The code takes the POST request and turns it into a GET request back to itself (via 303 redirect), so the browser can send the session cookie back and complete the auth flow. Just note the change is lost on XenForo upgrade.

Search for:
$connectedAccountRequest = $session->get('connectedAccountRequest');

Add this below it:
PHP:
if ($request->isPost() && !$connectedAccountRequest)
{
    $code = (string) $request->filter('code', 'str');
    $error = (string) $request->filter('error', 'str');

    if ($code !== '' || $error !== '')
    {
        $params = [];
        foreach (['code', 'state', 'error', 'error_description', 'denied'] AS $bounceKey)
        {
            $bounceValue = (string) $request->filter($bounceKey, 'str');
            if ($bounceValue !== '')
            {
                $params[$bounceKey] = $bounceValue;
            }
        }

        $bounceUrl = $app->options()->boardUrl . '/connected_account.php';
        if ($params)
        {
            $bounceUrl .= '?' . http_build_query($params);
        }

        $response->header('Referrer-Policy', 'no-referrer');
        $response->redirect($bounceUrl, 303);
        $response->send($request);

        exit;
    }
}

Awesome, thank you! I'll give this a try this evening.
 
Back
Top Bottom