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

[hold for payment 2023-08-30] [$2000] Security - Copy button is displayed without any secret key when the 2FA step 2 page is accessed directly through URL #19496

Closed
1 of 6 tasks
kbecciv opened this issue May 23, 2023 · 131 comments
Assignees
Labels
Bug Something is broken. Auto assigns a BugZero manager. Daily KSv2 External Added to denote the issue can be worked on by a contributor Reviewing Has a PR in review

Comments

@kbecciv
Copy link

kbecciv commented May 23, 2023

If you haven’t already, check out our contributing guidelines for onboarding and email [email protected] to request to join our Slack channel!


Action Performed:

  1. Got to https://staging.new.expensify.com/settings/security/two-factor-auth/verify on an account where you have not previously copied or downloaded 2FA secret keys.
  2. Sign in if not already.
  3. Notice you are not shown the 2FA secret key when the page loads. Nor if you go back, can you see the recovery codes on the previous page.

Expected Result:

Here are how we want to handle all of the various cases related to this issue:

2FA is not enabled, and the user loads:

2FA is enabled, and the user loads:

Actual Result:

Copy button is there without any secret key shown.

Workaround:

Unknown

Platforms:

Which of our officially supported platforms is this issue occurring on?

  • Android / native
  • Android / Chrome
  • iOS / native
  • iOS / Safari
  • MacOS / Chrome / Safari
  • MacOS / Desktop

Version Number: 1.3.17.0

Reproducible in staging?: Yes

Reproducible in production?: yes

If this was caught during regression testing, add the test name, ID and link from TestRail:

Email or phone of affected tester (no customers):

Logs: https://stackoverflow.com/c/expensify/questions/4856

Notes/Photos/Videos: Any additional supporting documentation

Screen.Recording.2023-05-24.at.2.28.55.AM.1.mov

Expensify/Expensify Issue URL:

Issue reported by: @adeel0202

Slack conversation: https://expensify.slack.com/archives/C049HHMV9SM/p1684420754597459

View all open jobs on GitHub

Upwork Automation - Do Not Edit
  • Upwork Job URL: https://www.upwork.com/jobs/~012f90e1d072b364da
  • Upwork Job ID: 1661463527223799808
  • Last Price Increase: 2023-06-14
@kbecciv kbecciv added Daily KSv2 Needs Reproduction Reproducible steps needed Bug Something is broken. Auto assigns a BugZero manager. labels May 23, 2023
@melvin-bot
Copy link

melvin-bot bot commented May 23, 2023

Triggered auto assignment to @joekaufmanexpensify (Bug), see https://stackoverflow.com/c/expensify/questions/14418 for more details.

@melvin-bot
Copy link

melvin-bot bot commented May 23, 2023

Bug0 Triage Checklist (Main S/O)

  • This "bug" occurs on a supported platform (ensure Platforms in OP are ✅)
  • This bug is not a duplicate report (check E/App issues and #expensify-bugs)
    • If it is, comment with a link to the original report, close the issue and add any novel details to the original issue instead
  • This bug is reproducible using the reproduction steps in the OP. S/O
    • If the reproduction steps are clear and you're unable to reproduce the bug, check with the reporter and QA first, then close the issue.
    • If the reproduction steps aren't clear and you determine the correct steps, please update the OP.
  • This issue is filled out as thoroughly and clearly as possible
    • Pay special attention to the title, results, platforms where the bug occurs, and if the bug happens on staging/production.
  • I have reviewed and subscribed to the linked Slack conversation to ensure Slack/Github stay in sync

@huzaifa-99
Copy link
Contributor

huzaifa-99 commented May 23, 2023

Proposal

Please re-state the problem that we are trying to solve in this issue.

We want to regenerate recovery codes when the user visits the security codes page from verify codes page after refreshing the screen no the verify codes page.

What is the root cause of that problem?

Currently the recovery codes are only regenerating in the security settings screen when the 'two factor authentication' option is clicked.

Session.toggleTwoFactorAuth(true);

What changes do you think we should make in order to solve the problem?

We should move the Session.toggleTwoFactorAuth(true); in SecuritySettingsPage.js#L43 before this line in CodesPage.js

Additionally, we can check if the recovery code is already there and fetch new one accordingly

if (!(props.account.recoveryCodes && props.account.twoFactorAuthSecretKey)) {
    Session.toggleTwoFactorAuth(true);
}

What alternative solutions did you explore? (Optional)

N/A

@joekaufmanexpensify
Copy link
Contributor

joekaufmanexpensify commented May 24, 2023

I can reproduce this on web. If I had to suspect why this happening, it's because typically when enabling 2FA, we require you to download or copy the recovery codes, before proceeding the step that has the secret key. Whereas by loading https://staging.new.expensify.com/settings/security/two-factor-auth/verify , the user is bypassing this required first step.

IMO, the best solution would be to redirect the user to the first page of the 2FA flow (to copy/download their recovery codes), if they try and load https://staging.new.expensify.com/settings/security/two-factor-auth/verify directly, and have niot previously copied or downloaded their recovery codes.

2023-05-24_15-58-57.mp4

@joekaufmanexpensify joekaufmanexpensify added External Added to denote the issue can be worked on by a contributor and removed Needs Reproduction Reproducible steps needed labels May 24, 2023
@melvin-bot melvin-bot bot changed the title Security - Copy button is displayed without any secret key when the 2FA step 2 page is accessed directly through URL [$1000] Security - Copy button is displayed without any secret key when the 2FA step 2 page is accessed directly through URL May 24, 2023
@melvin-bot
Copy link

melvin-bot bot commented May 24, 2023

Job added to Upwork: https://www.upwork.com/jobs/~012f90e1d072b364da

@melvin-bot
Copy link

melvin-bot bot commented May 24, 2023

Current assignee @joekaufmanexpensify is eligible for the External assigner, not assigning anyone new.

@melvin-bot
Copy link

melvin-bot bot commented May 24, 2023

Triggered auto assignment to Contributor-plus team member for initial proposal review - @aimane-chnaif (External)

@melvin-bot melvin-bot bot added the Help Wanted Apply this label when an issue is open to proposals by contributors label May 24, 2023
@melvin-bot
Copy link

melvin-bot bot commented May 24, 2023

Triggered auto assignment to @deetergp (External), see https://stackoverflow.com/c/expensify/questions/7972 for more details.

@kushu7
Copy link
Contributor

kushu7 commented May 24, 2023

Proposal

Please re-state the problem that we are trying to solve in this issue.

Copy button is displayed without any secret key when the 2FA step 2 page is accessed directly through URL

What is the root cause of that problem?

Its happening because user directly accessing settings/security/two-factor-auth/verify page. we are missing recoveryCodes and twoFactorAuthSecretKey.

What changes do you think we should make in order to solve the problem?

I digged more into this.
And find out it will require more refactoring as direct access is available for all pages.
My observation:

  • settings/security/two-factor-auth/enabled : We should only allow direct access when props.account.requiresTwoFactorAuth is true. otherwise redirect to 2FA CODES page.
  • settings/security/two-factor-auth/disable: We should only allow direct access when props.account.requiresTwoFactorAuth is true. otherwise redirect to 2FA CODES page.
  • settings/security/two-factor-auth/codes: We should only allow direct access when props.account.requiresTwoFactorAuth is false. otherwise redirect to 2FA ENABLED page.
  • settings/security/two-factor-auth/verify: We should not allow direct access.if props.account.requiresTwoFactorAuth is false then redirect it to 2FA CODES.
  • settings/security/two-factor-auth/success:We should only allow direct access when props.account.requiresTwoFactorAuth is true. if false redirect to 2FA CODES.

We can create action like this.

function checkAccessAndRedirectIfRequired() {
    const currentRoute = ReportUtils.getRouteFromLink(Navigation.getActiveRoute()).substring(1);
    const connectionID = Onyx.connect({
        key: ONYXKEYS.ACCOUNT,
        waitForCollectionCallback: true,
        callback: (account) => {
            Onyx.disconnect(connectionID);
            
            if (!account) {
                return;
            }
            const is2faEnabled = account.requiresTwoFactorAuth;
            if (currentRoute === ROUTES.SETTINGS_2FA_CODES) {
                if (is2faEnabled) return Navigation.navigate(ROUTES.SETTINGS_2FA_IS_ENABLED)
                clearTwoFactorAuthData();
                Session.toggleTwoFactorAuth(true);
                return;
            }
            // just redirect to CODES page direct access should not be allowed
            if (currentRoute === ROUTES.SETTINGS_2FA_VERIFY || currentRoute === ROUTES.SETTINGS_2FA_IS_ENABLED) {
                if (!is2faEnabled) Navigation.navigate(ROUTES.SETTINGS_2FA_CODES)
            }
            ... others handlers for page
        }
    });

}

And have to use in ALL 2FA pages. will handle all edge cases.

OLD understanding.

We should redirect user to 1st step and toggle2FA.

useEffect(() => {
if (props.account.requiresTwoFactorAuth) {
Navigation.navigate(ROUTES.SETTINGS_TWO_FACTOR_SUCCESS);
}
}, [props.account.requiresTwoFactorAuth]);

Can add below this function.

    useEffect(() => {
        if (props.account.recoveryCodes) {
            return;
        }
        Navigation.navigate(ROUTES.SETTINGS_2FA_CODES)
    }, [props.account.recoveryCodes])

and in CodePage we can add this

Session.toggleTwoFactorAuth(true); // we can use this in `useEffect`

We are doing this so it will solve our #19628 Issue when user directly open this page.

and can safely remove this line from here

Session.toggleTwoFactorAuth(true);

What alternative solutions did you explore? (Optional)

None

Video

newvid.mov

@melvin-bot
Copy link

melvin-bot bot commented May 24, 2023

Looks like something related to react-navigation may have been mentioned in this issue discussion.

As a reminder, please make sure that all proposals are not workarounds and that any and all attempt to fix the issue holistically have been made before proceeding with a solution. Proposals to change our DeprecatedCustomActions.js files should not be accepted.

Feel free to drop a note in #expensify-open-source with any questions.

@hoangzinh
Copy link
Contributor

hoangzinh commented May 25, 2023

Proposal

Please re-state the problem that we are trying to solve in this issue.

Security - Copy button is displayed without any secret key when the 2FA step 2 page is accessed directly through URL

What is the root cause of that problem?

=> That's reason why if we reload the Verify 2FA page or go to it by direct link, there is no recoveryCodes there.

What changes do you think we should make in order to solve the problem?

  • First of all, we need to update the way generating recovery codes + clean up it:

    • In the 1st page (CodesPage):

      • We need to move the code to generate 2FA data from here to this userEffect method of the 1st page of 2FA flow => we will check if account.recoverCodes is empty, we will call API to new 2FA data, otherwise do nothing. (preserve the code when user go back and forth)
      • We also need to remove clean up code here out of return function of useEffect. Otherwise, when we go to the Verify page first, then back to this 1st page, then go to the Verify page => this LOC will trigger and clear all 2FA auth data.
    • In the VerifyPage:

  • Secondly, we need to check and redirect with condition listed here and here

    • I'm imaging we will write a HOC like this (I prefer to use HOC because we can prevent unnecessary code trigger in 2FA steps/pages (componentDidMount/Update) when we're checking whether we need to redirect to any step or can stay at the current step). Which will check:
      • If OpenApp api is fetching => show full screen loading page (with key ONYXKEYS.IS_LOADING_REPORT_DATA)
      • In componentDidUpdate lifecycle (or useEffect for functional component), we will check if OpenApp api is done, then we will check:
        • if 2FA is enabled but current route is not IsEnabled page => navigate to IsEnable page.
        • Otherwise, if 2FA is not enabled but current route is IsEnabled page => navigate to CodesPage page (1st page).
        • Otherwise, if the recoveryCodes is not exists and current route is not the CodePage => navigate to CodePage.
    • Use this HOC in every steps of 2FA flow

@joekaufmanexpensify
Copy link
Contributor

@aimane-chnaif thoughts on these proposals?

@joekaufmanexpensify joekaufmanexpensify removed their assignment May 26, 2023
@joekaufmanexpensify joekaufmanexpensify added Bug Something is broken. Auto assigns a BugZero manager. and removed Bug Something is broken. Auto assigns a BugZero manager. labels May 26, 2023
@melvin-bot
Copy link

melvin-bot bot commented May 26, 2023

Triggered auto assignment to @Christinadobrzyn (Bug), see https://stackoverflow.com/c/expensify/questions/14418 for more details.

@melvin-bot

This comment was marked as outdated.

@joekaufmanexpensify
Copy link
Contributor

Adding an additional assignee as I'm OOO next week (until June 5th). Next steps here is to make sure we get these proposals reviewed, and hopefully select one!

@joekaufmanexpensify
Copy link
Contributor

I'd expect that you'd go back to the codes page. Do you agree @aimane-chnaif, @deetergp ?

@aimane-chnaif
Copy link
Contributor

We originally discussed to go back to Settings when individual routes.
@koko57 when click back button on success page, which page are you showing?

@koko57
Copy link
Contributor

koko57 commented Jul 18, 2023

So I've implemented it this way:
success page -> back to settings
verify page -> back to codes
but I can change that easily, if necessary

@aimane-chnaif
Copy link
Contributor

Works for me

@koko57
Copy link
Contributor

koko57 commented Jul 18, 2023

I've opened the draft PR in the morning, it was reviewed by my teammates. It's almost ready to be opened, but I have some problems with my android emulator and can't record videos and retest it once again, but it should be working (as there's no android specific changes here). I'll try to fix it and hopefully I'll be able to attach the videos tomorrow

@melvin-bot melvin-bot bot added Reviewing Has a PR in review Weekly KSv2 labels Jul 19, 2023
@koko57
Copy link
Contributor

koko57 commented Jul 19, 2023

Fixed the issue and added recordings for Android. PR opened: #23060

@koko57
Copy link
Contributor

koko57 commented Aug 2, 2023

@aimane-chnaif bumping for re-review 🙂

@joekaufmanexpensify
Copy link
Contributor

PR got merged last week!

@joekaufmanexpensify
Copy link
Contributor

Payment due here on 2023-08-30!

@joekaufmanexpensify joekaufmanexpensify changed the title [$2000] Security - Copy button is displayed without any secret key when the 2FA step 2 page is accessed directly through URL [hold for payment 2023-08-30] [$2000] Security - Copy button is displayed without any secret key when the 2FA step 2 page is accessed directly through URL Aug 28, 2023
@aimane-chnaif
Copy link
Contributor

Coming from #25518:
@joekaufmanexpensify I accepted offer from https://www.upwork.com/jobs/~01f029092225d9427e, so let's use this contract.

@joekaufmanexpensify
Copy link
Contributor

@aimane-chnaif just to clarify, you mean i'll take over payment for the contract you accepted in the above issue, and just handle payment in this issue using that contract? If so, sounds good to me!

@aimane-chnaif
Copy link
Contributor

@aimane-chnaif just to clarify, you mean i'll take over payment for the contract you accepted in the above issue, and just handle payment in this issue using that contract? If so, sounds good to me!

yes exactly. Thanks

@joekaufmanexpensify
Copy link
Contributor

Sounds good!

@joekaufmanexpensify
Copy link
Contributor

It took a while to get this one merged, but we discussed here, and given the amount of effort involved in this issue, there will be no penalty. This means we need to issue the following payments:

  • @aimane-chnaif - $2,000 for C+ review (bounty was increase in May to try and find proposals). Paid via upwork.
  • @adeel0202 - $250 for reporting bonus. Paid via Upwork.
  • @koko57 - payment handled separately via agency.

@joekaufmanexpensify joekaufmanexpensify added Daily KSv2 and removed Weekly KSv2 labels Aug 30, 2023
@joekaufmanexpensify
Copy link
Contributor

Original upwork job closed, so I created a new one here to pay @adeel0202 .

Separately, @sakluger got assigned a duplicate issue to pay @aimane-chnaif for their review in this issue and already hired them there, so we're going to use that job for the purposes of paying @aimane-chnaif.

@joekaufmanexpensify
Copy link
Contributor

@adeel0202 offer sent for $250!

@adeel0202
Copy link
Contributor

@adeel0202 offer sent for $250!

Accepted, thanks.

@joekaufmanexpensify
Copy link
Contributor

@adeel0202 $250 sent and contract ended!

@joekaufmanexpensify
Copy link
Contributor

@aimane-chnaif $2,000 sent for the upwork contract you accepted in this issue, and contract ended.

@joekaufmanexpensify
Copy link
Contributor

Closing as this one's all set. Thanks everyone!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Something is broken. Auto assigns a BugZero manager. Daily KSv2 External Added to denote the issue can be worked on by a contributor Reviewing Has a PR in review
Projects
None yet
Development

No branches or pull requests