Commit graph

17 commits

Author SHA1 Message Date
epriestley 5a89da12e2 When users have no password on their account, guide them through the "reset password" flow in the guise of "set password"
Summary:
Depends on D20119. Fixes T9512. When you don't have a password on your account, the "Password" panel in Settings is non-obviously useless: you can't provide an old password, so you can't change your password.

The correct remedy is to "Forgot password?" and go through the password reset flow. However, we don't guide you to this and it isn't really self-evident.

Instead:

  - Guide users to the password reset flow.
  - Make it work when you're already logged in.
  - Skin it as a "set password" flow.

We're still requiring you to prove you own the email associated with your account. This is a pretty weak requirement, but maybe stops attackers who use the computer at the library after you do in some bizarre emergency and forget to log out? It would probably be fine to just let users "set password", this mostly just keeps us from having two different pieces of code responsible for setting passwords.

Test Plan:
  - Set password as a logged-in user.
  - Reset password on the normal flow as a logged-out user.

Reviewers: amckinley

Reviewed By: amckinley

Subscribers: revi

Maniphest Tasks: T9512

Differential Revision: https://secure.phabricator.com/D20120
2019-02-12 15:19:46 -08:00
epriestley 6f3bd13cf5 Begin adding more guidance to the "One-Time Login" flow
Summary:
Ref T13244. See PHI774. If an install does not use password auth, the "one-time login" flow (via "Welcome" email or "bin/auth recover") is pretty rough. Current behavior:

  - If an install uses passwords, the user is prompted to set a password.
  - If an install does not use passwords, you're dumped to `/settings/external/` to link an external account. This is pretty sketchy and this UI does not make it clear what users are expected to do (link an account) or why (so they can log in).

Instead, improve this flow:

  - Password reset flow is fine.
  - (Future Change) If there are external linkable accounts (like Google) and the user doesn't have any linked, I want to give users a flow like a password reset flow that says "link to an external account".
  - (This Change) If you're an administrator and there are no providers at all, go to "/auth/" so you can set something up.
  - (This Change) If we don't hit on any other rules, just go home?

This may be tweaked a bit as we go, but basically I want to refine the "/settings/external/" case into a more useful flow which gives users more of a chance of surviving it.

Test Plan: Logged in with passwords enabled (got password reset), with nothing enabled as an admin (got sent to Auth), and with something other than passwords enabled (got sent home).

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13244

Differential Revision: https://secure.phabricator.com/D20094
2019-02-05 14:17:25 -08:00
epriestley ff49d1ef77 Allow "bin/auth recover" to generate a link which forces a full login session
Summary:
Depends on D19902. Ref T13222. This is mostly a "while I'm in here..." change since MFA is getting touched so much anyway.

Doing cluster support, I sometimes need to log into user accounts on instances that have MFA. I currently accomplish this by doing `bin/auth recover`, getting a parital session, and then forcing it into a full session in the database. This is inconvenient and somewhat dangerous.

Instead, allow `bin/auth recover` to generate a link that skips the "partial session" stage: adding required MFA, providing MFA, and signing legalpad documents.

Anyone who can run `bin/auth recover` can do this anyway, this just reduces the chance I accidentally bypass MFA on the wrong session when doing support stuff.

Test Plan:
  - Logged in with `bin/auth recover`, was prompted for MFA.
  - Logged in with `bin/auth recover --force-full-session`, was not prompted for MFA.
  - Did a password reset, followed reset link, was prompted for MFA.

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13222

Differential Revision: https://secure.phabricator.com/D19903
2018-12-28 00:15:36 -08:00
epriestley ad4db9b2f3 Separate "Set/Reset Password" from "Change Password"
Summary:
See PHI223. Ref T13024. There's a remaining registration/login order issue after the other changes in T13024: we lose track of the current URI when we go through the MFA flow, so we can lose "Set Password" at the end of the flow.

Specifically, the flow goes like this today:

  - User clicks the welcome link in email.
  - They get redirected to the "set password" settings panel.
  - This gets pre-empted by Legalpad (although we'll potentially survive this with the URI intact).
  - This also gets pre-empted by the "Set MFA" workflow. If the user completes this flow, they get redirected to a `/auth/multifactor/?id=123` sort of URI to highlight the factor they added. This causes us to lose the `/settings/panel/password/blah/blah?key=xyz` URI.

The ordering on this is also not ideal; it's preferable to start with a password, then do the other steps, so the user can return to the flow more easily if they are interrupted.

Resolve this by separating the "change your password" and "set/reset your password" flows onto two different pages. This copy/pastes a bit of code, but both flows end up simpler so it feels reasonable to me overall.

We don't require a full session for "set/reset password" (so you can do it if you don't have MFA/legalpad yet) and do it first.

This works better and is broadly simpler for users.

Test Plan:
  - Required MFA + legalpad, invited a user via email, registered.
    - Before: password set flow got lost when setting MFA.
    - After: prompted to set password, then sign documents, then set up MFA.
  - Reset password (with MFA confgiured, was required to MFA first).
  - Tried to reset password without a valid reset key, wasn't successful.
  - Changed password using existing flow.
  - Hit various (all?) error cases (short password, common password, mismatch, missing password, etc).

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13024

Differential Revision: https://secure.phabricator.com/D18840
2017-12-26 08:34:14 -08:00
Chad Little ba4b936dff Use Log In vs. Login when it's a verb
Summary: Cursory research indicates that "login" is a noun, referring to a form, and "log in" is a verb, referring to the action of logging in. I went though every instances of 'login' I could find and tried to clarify all this language. Also, we have "Phabricator" on the registration for like 4-5 times, which is a bit verbose, so I tried to simplify that language as well.

Test Plan: Tested logging in and logging out. Pages feel simpler.

Reviewers: epriestley

Reviewed By: epriestley

Subscribers: Korvin

Differential Revision: https://secure.phabricator.com/D18322
2017-08-02 12:26:47 -07:00
epriestley 3d816e94df Rename "PhabricatorHash::digest()" to "weakDigest()"
Summary: Ref T12509. This encourages code to move away from HMAC+SHA1 by making the method name more obviously undesirable.

Test Plan: `grep`, browsed around.

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T12509

Differential Revision: https://secure.phabricator.com/D17632
2017-04-06 15:43:33 -07:00
epriestley abeab59448 Fix redirect to Password settings panel after "Reset Password" login
Summary: Fixes T11107. The URI change here meant we were dropping the "key" parameter, which allows you to set a new password without knowing your old one.

Test Plan: Reset password, didn't need to provide old one anymore.

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T11107

Differential Revision: https://secure.phabricator.com/D16075
2016-06-07 14:07:40 -07:00
epriestley a837c3d73e Make temporary token storage/schema more flexible
Summary:
Ref T10603. This makes minor updates to temporary tokens:

  - Rename `objectPHID` (which is sometimes used to store some other kind of identifier instead of a PHID) to `tokenResource` (i.e., which resource does this token permit access to?).
  - Add a `userPHID` column. For LFS tokens and some other types of tokens, I want to bind the token to both a resource (like a repository) and a user.
  - Add a `properties` column. This makes tokens more flexible and supports custom behavior (like scoping LFS tokens even more tightly).

Test Plan:
- Ran `bin/storage upgrade -f`, got a clean upgrade.
- Viewed one-time tokens.
- Revoked one token.
- Revoked all tokens.
- Performed a one-time login.
- Performed a password reset.
- Added an MFA token.
- Removed an MFA token.
- Used a file token to view a file.
- Verified file token was removed after viewing file.
- Linked my account to an OAuth1 account (Twitter).

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T10603

Differential Revision: https://secure.phabricator.com/D15478
2016-03-16 09:33:38 -07:00
epriestley 8e3ea4e034 Use new modular temporary auth token constants in one-time login and password reset flows
Summary:
Ref T10603. This converts existing hard-codes to modular constants.

Also removes one small piece of code duplication.

Test Plan:
  - Performed one-time logins.
  - Performed a password reset.
  - Verified temporary tokens were revoked properly.

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T10603

Differential Revision: https://secure.phabricator.com/D15476
2016-03-16 09:33:24 -07:00
epriestley 59c9317101 Prevent mailing lists from being bin/auth recover'd
Summary:
Fixes T9610.

  - We currently permit you to `bin/auth recover` users who can not establish web sessions (but this will never work). Prevent this.
  - We don't emit a tailored error if you follow one of these links. Tailor the error.

Even with the first fix, you can still hit the second case by doing something like:

  - Recover a normal user.
  - Make them a mailing list in the DB.
  - Follow the recovery link.

The original issue here was an install that did a large migration and set all users to be mailing lists. Normal installs should never encounter this, but it's not wholly unreasonable to have daemons or mailing lists with the administrator flag.

Test Plan:
  - Tried to follow a recovery link for a mailing list.
  - Tried to generate a recovery link for a mailing list.
  - Generated and followed a recovery link for a normal administrator.

{F906342}

```
epriestley@orbital ~/dev/phabricator $ ./bin/auth recover tortise-list
Usage Exception: This account ("tortise-list") can not establish web sessions, so it is not possible to generate a functional recovery link. Special accounts like daemons and mailing lists can not log in via the web UI.
```

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T9610

Differential Revision: https://secure.phabricator.com/D14325
2015-10-24 18:12:56 -07:00
epriestley b4b5d60f77 Fix 'key'/'type' swap in email reset / one-time-login controller
Summary: Fixes T9046. These got swapped around during refactoring.

Test Plan:
  - Used `bin/auth recover` prior to patch (failed).
  - Used `bin/auth recover` after patch (worked).

Reviewers: joshuaspence, chad

Reviewed By: chad

Subscribers: epriestley

Maniphest Tasks: T9046

Differential Revision: https://secure.phabricator.com/D13778
2015-08-03 08:01:43 -07:00
Chad Little 36103dfa18 Update Auth for handleRequest
Summary: Updates Auth app for handleRequest

Test Plan: Tested what I could, Log in, Log out, Change Password, New account, Verify account... but extra eyes very helpful here.

Reviewers: epriestley

Reviewed By: epriestley

Subscribers: epriestley, Korvin

Maniphest Tasks: T8628

Differential Revision: https://secure.phabricator.com/D13748
2015-08-01 16:49:27 -07:00
epriestley 4a566f9e5d Allow passwords to be edited even if account.editable is false
Summary:
Fixes T5900. We have some very old code here which does not let you update your password if the `account.editable` flag is set.

This was approximately introduced in D890, and I think it was mostly copy/pasted at that point. I'm not sure this ever really made sense. The option is not documented as affecting this, for example. In the modern environment of auth providers, it definitely does not make sense.

Instead, always allow users to change passwords if the install has a password provider configured.

Test Plan:
  - Set `account.editable` to false.
  - Used a password reset link.

Reviewers: btrahan

Reviewed By: btrahan

Subscribers: epriestley

Maniphest Tasks: T5900

Differential Revision: https://secure.phabricator.com/D10331
2014-08-21 15:35:43 -07:00
epriestley 6232e9676c Don't send reset links to unverified addresses on accounts with verified addresses
Summary:
Via HackerOne. If a user adds an email address and typos it, entering `alinculne@gmailo.com`, and it happens to be a valid address which an evil user controls, the evil user can request a password reset and compromise the account.

This strains the imagination, but we can implement a better behavior cheaply.

  - If an account has any verified addresses, only send to verified addresses.
  - If an account has no verified addresses (e.g., is a new account), send to any address.

We've also received several reports about reset links not being destroyed as aggressively as researchers expect. While there's no specific scenario where this does any harm, revoke all outstanding reset tokens when a reset link is used to improve the signal/noise ratio of the reporting channel.

Test Plan:
  - Tried to send a reset link to an unverified address on an account with a verified address (got new error).
  - Tried to send a reset link to a verified adddress on an account with a verified address (got email).
  - Tried to send a reset link to an invalid address (got old error).
  - Tried to send a reset link to an unverified address on an account with only unverified addresses -- a new user (got email).
  - Requested several reset links, used one, verified all the others were revoked.

Reviewers: btrahan

Reviewed By: btrahan

Subscribers: epriestley

Differential Revision: https://secure.phabricator.com/D10206
2014-08-11 12:13:09 -07:00
Joshua Spence f4b05312cd Fix broken references to auth adapters
This was broken in D9999 but somehow didn't fail linting or unit tests.

Auditors: epriestley
2014-07-22 21:20:45 +10:00
epriestley 83112cc2e8 Move email verification into PhabricatorUserEditor
Summary: Both email verify and welcome links now verify email, centralize them and record them in the user activity log.

Test Plan:
  - Followed a "verify email" link and got verified.
  - Followed a "welcome" (verifying) link.
  - Followed a "reset" (non-verifying) link.
  - Looked in the activity log for the verifications.

Reviewers: btrahan

Reviewed By: btrahan

Subscribers: epriestley

Differential Revision: https://secure.phabricator.com/D9284
2014-06-03 16:45:18 -07:00
epriestley f1534e6feb Make password reset emails use one-time tokens
Summary:
Ref T4398. This code hadn't been touched in a while and had a few crufty bits.

**One Time Resets**: Currently, password reset (and similar links) are valid for about 48 hours, but we always use one token to generate them (it's bound to the account). This isn't horrible, but it could be better, and it produces a lot of false positives on HackerOne.

Instead, use TemporaryTokens to make each link one-time only and good for no more than 24 hours.

**Coupling of Email Verification and One-Time Login**: Currently, one-time login links ("password reset links") are tightly bound to an email address, and using a link verifies that email address.

This is convenient for "Welcome" emails, so the user doesn't need to go through two rounds of checking email in order to login, then very their email, then actually get access to Phabricator.

However, for other types of these links (like those generated by `bin/auth recover`) there's no need to do any email verification.

Instead, make the email verification part optional, and use it on welcome links but not other types of links.

**Message Customization**: These links can come out of several workflows: welcome, password reset, username change, or `bin/auth recover`. Add a hint to the URI so the text on the page can be customized a bit to help users through the workflow.

**Reset Emails Going to Main Account Email**: Previously, we would send password reset email to the user's primary account email. However, since we verify email coming from reset links this isn't correct and could allow a user to verify an email without actually controlling it.

Since the user needs a real account in the first place this does not seem useful on its own, but might be a component in some other attack. The user might also no longer have access to their primary account, in which case this wouldn't be wrong, but would not be very useful.

Mitigate this in two ways:

  - First, send to the actual email address the user entered, not the primary account email address.
  - Second, don't let these links verify emails: they're just login links. This primarily makes it more difficult for an attacker to add someone else's email to their account, send them a reset link, get them to login and implicitly verify the email by not reading very carefully, and then figure out something interesting to do (there's currently no followup attack here, but allowing this does seem undesirable).

**Password Reset Without Old Password**: After a user logs in via email, we send them to the password settings panel (if passwords are enabled) with a code that lets them set a new password without knowing the old one.

Previously, this code was static and based on the email address. Instead, issue a one-time code.

**Jump Into Hisec**: Normally, when a user who has multi-factor auth on their account logs in, we prompt them for factors but don't put them in high security. You usually don't want to go do high-security stuff immediately after login, and it would be confusing and annoying if normal logins gave you a "YOU ARE IN HIGH SECURITY" alert bubble.

However, if we're taking you to the password reset screen, we //do// want to put the user in high security, since that screen requires high security. If we don't do this, the user gets two factor prompts in a row.

To accomplish this, we set a cookie when we know we're sending the user into a high security workflow. This cookie makes login finalization upgrade all the way from "partial" to "high security", instead of stopping halfway at "normal". This is safe because the user has just passed a factor check; the only reason we don't normally do this is to reduce annoyance.

**Some UI Cleanup**: Some of this was using really old UI. Modernize it a bit.

Test Plan:
  - **One Time Resets**
    - Used a reset link.
    - Tried to reuse a reset link, got denied.
    - Verified each link is different.
  - **Coupling of Email Verification and One-Time Login**
    - Verified that `bin/auth`, password reset, and username change links do not have an email verifying URI component.
    - Tried to tack one on, got denied.
    - Used the welcome email link to login + verify.
    - Tried to mutate the URI to not verify, or verify something else: got denied.
  - **Message Customization**
    - Viewed messages on the different workflows. They seemed OK.
  - **Reset Emails Going to Main Account Email**
    - Sent password reset email to non-primary email.
    - Received email at specified address.
    - Verified it does not verify the address.
  - **Password Reset Without Old Password**
    - Reset password without knowledge of old one after email reset.
    - Tried to do that without a key, got denied.
    - Tried to reuse a key, got denied.
  - **Jump Into Hisec**
    - Logged in with MFA user, got factor'd, jumped directly into hisec.
    - Logged in with non-MFA user, no factors, normal password reset.
  - **Some UI Cleanup**
    - Viewed new UI.
  - **Misc**
    - Created accounts, logged in with welcome link, got verified.
    - Changed a username, used link to log back in.

Reviewers: btrahan

Reviewed By: btrahan

Subscribers: epriestley

Maniphest Tasks: T4398

Differential Revision: https://secure.phabricator.com/D9252
2014-05-22 10:41:00 -07:00