Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix event listener race condition on login-form #36286

Merged
merged 1 commit into from
Feb 7, 2023

Conversation

SystemKeeper
Copy link
Contributor

@SystemKeeper SystemKeeper commented Jan 22, 2023

Summary

We received reports about the error "State token does not match" when trying to login with talk-ios (see nextcloud/talk-ios#1017). I have seen this error myself from time to time, but wasn't able to pinpoint it to when exactly it happens. I took a closer look at the requests / responses received and noticed, that usually we should see something like this

GET /index.php/login/flow/grant?stateToken=<TOKEN>&clientIdentifier=&user=&direct=0

but in some cases it was just like this

GET /index.php/login/flow/grant?

so without any query parameters. The login process itself (username, password) does work fine, but fails after granting access with the error mentioned above.
The page itself is rendered correctly, so the forms actions include the parameters as seen in the first request above. As this won't work natively (at least not on iOS), we need a small javascript snippet (authpicker.js) to to a redirect, instead of a the native browser action. Problem is that the listener for this to happen is added when the document is ready, but the user is actually able to press "Log in" before the listener is added, therefore doing a native browser action with the query parameters removed.

How to test:

  • Comment out this code
    document.getElementById('login-form').addEventListener('submit', function (e) {
    e.preventDefault();
    document.location.href = e.target.attributes.action.value
    })
  • Try to login using flow v1
  • See that you receive "State token does not match" at the end

Because this code is still using jQuery and therefore considered legacy, I went for disabling the button until the corresponding jQuery code ran.

CC: @Ivansss

Checklist

@szaimen szaimen added the 3. to review Waiting for reviews label Jan 22, 2023
@szaimen szaimen added this to the Nextcloud 26 milestone Jan 22, 2023
@szaimen szaimen requested review from a team, ArtificialOwl, icewind1991 and come-nc and removed request for a team January 22, 2023 12:43
@come-nc come-nc requested a review from artonge January 23, 2023 08:09
Copy link
Contributor

@artonge artonge left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense :)

@kesselb
Copy link
Contributor

kesselb commented Jan 23, 2023

Thanks for your pull request 👍

I think that could explain this error: #32387

But the error shown to the user is a bit different.

@SystemKeeper
Copy link
Contributor Author

I think that could explain this error: #32387

But this points to V2?! But maybe a similar error?

@SystemKeeper
Copy link
Contributor Author

Ah, LoginV2 uses the same script, sorry. In this case we should add „disabled“ to the V2 template as well?

@kesselb
Copy link
Contributor

kesselb commented Jan 23, 2023

But this points to V2?!

Well spotted ;)
I don't know to be honest.

@SystemKeeper
Copy link
Contributor Author

But this points to V2?!

Well spotted ;) I don't know to be honest.

😉

I guess it makes sense, looking at the V2 form we have the same situation here:

<form id="login-form" action="<?php p($urlGenerator->linkToRouteAbsolute('core.ClientFlowLoginV2.grantPage', ['stateToken' => $_['stateToken'], 'user' => $_['user']])) ?>" method="get">

so that could very well lead to the same problem. I’ll take a look at this.

@SystemKeeper SystemKeeper force-pushed the bugfix/noid/fix-sending-state-token-in-flowv1 branch from 618a151 to bbb490d Compare January 23, 2023 18:51
@SystemKeeper
Copy link
Contributor Author

I think that could explain this error: #32387

I tested this with the steps outlined in the first post and the error in #32387 is then reproducible. I added the same disabled property to the V2 form now.

Copy link
Member

@ChristophWurst ChristophWurst left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤯

@kesselb kesselb added 4. to release Ready to be released and/or waiting for tests to finish and removed 3. to review Waiting for reviews labels Feb 7, 2023
@kesselb kesselb merged commit 36347cb into master Feb 7, 2023
@kesselb kesselb deleted the bugfix/noid/fix-sending-state-token-in-flowv1 branch February 7, 2023 10:02
@welcome
Copy link

welcome bot commented Feb 7, 2023

Thanks for your first pull request and welcome to the community! Feel free to keep them coming! If you are looking for issues to tackle then have a look at this selection: https://github.com/nextcloud/server/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22

@kesselb
Copy link
Contributor

kesselb commented Feb 7, 2023

/backport to stable25

@kesselb
Copy link
Contributor

kesselb commented Feb 7, 2023

/backport to stable24

@ChristophWurst
Copy link
Member

/backport to stable25

@ChristophWurst
Copy link
Member

/backport to stable24

@backportbot-nextcloud
Copy link

The backport to stable25 failed. Please do this backport manually.

@backportbot-nextcloud
Copy link

The backport to stable24 failed. Please do this backport manually.

@blizzz blizzz mentioned this pull request Feb 9, 2023
@solracsf
Copy link
Member

/backport to stable25

@solracsf
Copy link
Member

/backport to stable24

@backportbot-nextcloud
Copy link

The backport to stable24 failed. Please do this backport manually.

@SystemKeeper
Copy link
Contributor Author

SystemKeeper commented Feb 22, 2023

Not sure we need a backport to stable24, because there it is a link, instead of a form:

<a href="<?php p($urlGenerator->linkToRoute('core.ClientFlowLogin.grantPage', ['stateToken' => $_['stateToken'], 'clientIdentifier' => $_['clientIdentifier'], 'oauthState' => $_['oauthState'], 'user' => $_['user'], 'direct' => $_['direct']])) ?>">
<input type="submit" class="login primary icon-confirm-white" value="<?php p($l->t('Log in')) ?>">
</a>

And there's no event handler:

https://github.com/nextcloud/server/blob/stable24/core/js/login/authpicker.js

But I'm not sure what the reason for the change was in the first place.

@kesselb
Copy link
Contributor

kesselb commented Feb 22, 2023

I guess 25 is fine then.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
4. to release Ready to be released and/or waiting for tests to finish feature: authentication
Projects
None yet
8 participants