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

[Brig] Move password verification to the AuthenticationSubsystem, move to Argon2id with default settings. #4271

Open
wants to merge 17 commits into
base: develop
Choose a base branch
from

Conversation

elland
Copy link
Contributor

@elland elland commented Sep 26, 2024

https://wearezeta.atlassian.net/browse/WPB-9746

Checklist

  • Add a new entry in an appropriate subdirectory of changelog.d
  • Read and follow the PR guidelines

@echoes-hq echoes-hq bot added the echoes: security Security related changes or defects label Sep 26, 2024
@zebot zebot added the ok-to-test Approved for running tests in CI, overrides not-ok-to-test if both labels exist label Sep 26, 2024
@fisx fisx changed the title Move password verification to the AuthenticationSubsystem, move to Argon2id with default settings. [WPB-9746] Move password verification to the AuthenticationSubsystem, move to Argon2id with default settings. Sep 26, 2024
@elland elland changed the title [WPB-9746] Move password verification to the AuthenticationSubsystem, move to Argon2id with default settings. [Brig] Move password verification to the AuthenticationSubsystem, move to Argon2id with default settings. Sep 26, 2024
@elland elland force-pushed the wpb-9746/password branch 2 times, most recently from f6c408d to 1bdae8c Compare September 26, 2024 13:31
Copy link
Contributor

@mdimjasevic mdimjasevic left a comment

Choose a reason for hiding this comment

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

Here is a partial review

Comment on lines 171 to 174
salt <- newSalt 32
salt <- newSalt 16
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't have the context, but why this change?

Comment on lines +285 to +287
-- CryptoFailed occurs when salt, output or input are too small/big.
-- since we control those values ourselves, it should never have a runtime error
CryptoFailed cErr -> error $ "Impossible error: " <> show cErr
Copy link
Contributor

Choose a reason for hiding this comment

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

So still something to change given the comment?

Comment on lines +358 to +366

-------------------------------------------------------------------------------
-- Generate test passwords, benchmark

genTestPasswords :: IO [(Text, Text)]
genTestPasswords = replicateM 100 do
pwd <- genPassword
hash <- mkSafePassword pwd
pure (fromPlainTextPassword pwd, fromPassword hash)
Copy link
Contributor

Choose a reason for hiding this comment

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

This sounds like it belongs to a test module instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Requires access to private functions, unsafe to deconstruct the opaque password type. I should document it.

import Wire.UserKeyStore

data AuthenticationSubsystem m a where
VerifyPassword :: Local UserId -> PlainTextPassword6 -> AuthenticationSubsystem m ()
VerifyPasswordE :: Local UserId -> PlainTextPassword6 -> AuthenticationSubsystem m ()
Copy link
Contributor

Choose a reason for hiding this comment

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

What is "E" in the name?

Comment on lines +35 to +37
VerifyPassword :: PlainTextPassword6 -> Password -> AuthenticationSubsystem m (Bool, PasswordStatus)
VerifyUserPassword :: UserId -> PlainTextPassword6 -> AuthenticationSubsystem r (Bool, PasswordStatus)
VerifyProviderPassword :: ProviderId -> PlainTextPassword6 -> AuthenticationSubsystem r (Bool, PasswordStatus)
Copy link
Contributor

Choose a reason for hiding this comment

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

How is the 6-character password topic related to the Scrypt vs. Argon2id topic? Does the choice of algorithm apply the minimal length?

Comment on lines +281 to +282
PasswordStore.lookupHashedProviderPassword pid
>>= maybe (throw AuthenticationSubsystemBadCredentials) pure
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
PasswordStore.lookupHashedProviderPassword pid
>>= maybe (throw AuthenticationSubsystemBadCredentials) pure
PasswordStore.lookupHashedProviderPassword pid >>= noteS @'AuthenticationSubsystemBadCredentials

Comment on lines +292 to +293
PasswordStore.lookupHashedPassword uid
>>= maybe (throw AuthenticationSubsystemBadCredentials) pure
Copy link
Contributor

Choose a reason for hiding this comment

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

ditto

@@ -16,6 +16,12 @@ interpretPasswordStore casClient =
runEmbedded (runClient casClient) . \case
UpsertHashedPassword uid password -> embed $ updatePasswordImpl uid password
LookupHashedPassword uid -> embed $ lookupPasswordImpl uid
LookupHashedProviderPassword pid -> embed $ lookupProviderPasswordImpl pid
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is there a need to treat provider password differently, i.e., why do we have this action?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, different table.

suspendTimeout: 4
suspendTimeout: 10
Copy link
Contributor

Choose a reason for hiding this comment

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

Why this change?

@@ -100,6 +106,7 @@ registerOAuthClient (OAuthClientConfig name uri) = do
createSecret :: (MonadIO m) => m OAuthClientPlainTextSecret
createSecret = OAuthClientPlainTextSecret <$> rand32Bytes

-- TODO(elland): figure out why
Copy link
Contributor

Choose a reason for hiding this comment

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

Something still to do.

@mdimjasevic
Copy link
Contributor

Have you searched for all usages of mkSafePasswordScrypt and checked that's as expected?

Copy link
Contributor

@mdimjasevic mdimjasevic left a comment

Choose a reason for hiding this comment

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

Some more comments inlined.

Given that this is changing the default hashing algorithm, and we forgot to do it before in some places, what would be good tests to add to capture this change?

authenticate u pw =
-- TODO: Move this logic into auth subsystem.
Copy link
Contributor

Choose a reason for hiding this comment

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

Still something to do.

@@ -225,10 +231,10 @@ reauthenticate u pw =
where
maybeReAuth pw' = case pw of
Nothing -> do
musr <- lookupUser NoPendingInvitations u
musr <- wrapClientE $ lookupUser NoPendingInvitations u
Copy link
Contributor

Choose a reason for hiding this comment

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

Don't we have an equivalent in the UserStore effect?

@@ -265,20 +273,31 @@ activateAccountKey key val = do
lift $ sendApprovalConfirmMail name email
pure . Just $ Public.ProviderActivationResponse email

getActivationCodeH :: (Member GalleyAPIAccess r, Member VerificationCodeSubsystem r) => EmailAddress -> (Handler r) Code.KeyValuePair
getActivationCodeH ::
Copy link
Contributor

Choose a reason for hiding this comment

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

We could drop this wai-routes convention of ending handler names with "H" now that you've already changed the line.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
echoes: security Security related changes or defects ok-to-test Approved for running tests in CI, overrides not-ok-to-test if both labels exist
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants