Edit: Second customer encountered same problem in https://www.phpbb.com/community/viewtop ... &t=2511881, and same workaround was necessary for them.
Thus far, we've been able to confirm that the issue is happening because the login form received as part of index.php has a current time stamp but a "wrong" session ID. I say "wrong" because it's not the session ID that phpBB then has and uses during all subsequent steps, start with the POST ucp.php?mode=login that fails with "invalid form."
With appropriate debug logging we've confirmed that "the session ID is different" is in fact the reason why the login fails with "invalid form". The subsequent re-attempt using the login form re-presented during the failure is no longer the login form from index.php, and has also been built with the "correct" current session ID; and so this second login attempt succeeds when POSTed.
I'm thinking "caching" is still the best reason to have "an index page containing a login form with a current time stamp but the wrong session ID"; e.g. that rendering of the index page & login form was made for someone else and not "your session", but the cache delivered the previously-built page containing the previous page's session ID. Someone who has a better grasp (or any grasp, really, since that would still be better than mine) of session ID mechanics might have additional logical reasons for "the session ID changed between the time of GET index.php and then trying to POST the login form contained in that index.php page."
If there is "something we do on login form templates to prevent them from being cached", but which is something we haven't been doing for the index.php template -- and have been "getting away with it" until now, because we hadn't been using add_form_token() or check_form_token() on index.php's login form -- maybe that would be relevant to this discussion too.
The other reason I wanted to post here was because of something that bugged me when investigating the code on this. phpBB ACP General tab, Server Configuration, Security settings has a setting for "Tie forms to guest sessions". The code that seemingly is intended to react to this is right in the add_form_token() and check_form_token() that I've been looking at, but is written as:
Code: Select all
$token_sid = ($user->data['user_id'] == ANONYMOUS && !empty($config['form_token_sid_guests'])) ? $user->session_id : '';
So I could have suggested to the current user to "try turning off Tie forms to guest sessions", but I didn't think that would actually have any effect. Is there a reason I'm missing for why "!empty()" is actually the intended and required test here?