Skip to content

[SQSERVICES-1931] wire server allow backend to enforce stronger password restrictions when setting a password#3137

Merged
battermann merged 29 commits intodevelopfrom
SQSERVICES-1931-wire-server-allow-backend-to-enforce-stronger-password-restrictions-when-setting-a-password
Mar 15, 2023
Merged

[SQSERVICES-1931] wire server allow backend to enforce stronger password restrictions when setting a password#3137
battermann merged 29 commits intodevelopfrom
SQSERVICES-1931-wire-server-allow-backend-to-enforce-stronger-password-restrictions-when-setting-a-password

Conversation

@battermann
Copy link
Contributor

@battermann battermann commented Mar 8, 2023

https://wearezeta.atlassian.net/browse/SQSERVICES-1931

  • Changed PlainTextPassword type so that it contains a text range according to the previous constraint with a min of 6 characters
  • Introduced a new type PlainTextPasswordMinLength8 with a text range with a min of 8 characters
  • Used the new type with min length 8 in the following places:
    • NewProviderResponse
    • NewUser
    • NewRawUser
    • PasswordChange
    • CompletePasswordReset
  • Updated golden tests
  • Updated integration tests
  • Added integration tests which verifies that passwords with less than 8 chars are rejected with a 400 status code for the following scenarios:
    • register user
    • set/change password
    • password reset
  • Introduced convenience functions plainTextPasswordUnsafe and plainTextPasswordLegacyUnsafe to use where we need to construct a password from a string (in the prod code, these should be used with caution)
  • toLegacy exists to convert from the new password type to the legacy type, which should always succeed because the constraints of the new type are stronger

It's currently not tested that login with an existing password with a length of less 8 characters still works. But according to how this is implemented, there is no reason it should not. Unfortunately, this would be very difficult to test, as it is not possible to create test users with shorter passwords anymore.

Checklist

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

@zebot zebot added the ok-to-test Approved for running tests in CI, overrides not-ok-to-test if both labels exist label Mar 8, 2023
@battermann battermann marked this pull request as ready for review March 9, 2023 14:54
@battermann
Copy link
Contributor Author

I am open to other naming suggestions, e.g. call the old/legacy password type PlainTextPasswordLegacy and the new one just PlainTextPassword?

Copy link
Contributor

@fisx fisx left a comment

Choose a reason for hiding this comment

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

running gundeck integration tests locally i get this:

    Tokens
      register a push token:                                          FAIL
        Exception: Safe.readNote no parse on "NO_HEADER_VALUE", unable to parse Location header
        CallStack (from HasCallStack):
          readNote, called at test/integration/API.hs:1253:7 in main:API
        Use -p '!/RealAWS/&&/Tokens.register a push token/' to rerun this test only.
      unregister a push token:                                        FAIL
        Exception: Safe.readNote no parse on "NO_HEADER_VALUE", unable to parse Location header
        CallStack (from HasCallStack):
          readNote, called at test/integration/API.hs:1253:7 in main:API
        Use -p '!/RealAWS/&&/unregister a push token/' to rerun this test only.
    Websocket pingpong
      data-level pings produce pongs:                                 OK (1.00s)
      control pings with payload produce pongs with the same payload: OK (1.00s)
      data non-pings are ignored:                                     OK (2.00s)
    Redis migration
      redis migration should work:                                    FAIL
        Exception: Error executing request: Safe.readNote no parse on "NO_HEADER_VALUE", unable to parse Location header
        CallStack (from HasCallStack):
          readNote, called at test/integration/API.hs:1253:7 in main:API
        CallStack (from HasCallStack):
          error, called at src/Bilge/Assert.hs:101:18 in bilge-0.22.0-inplace:Bilge.Assert
          <!!, called at src/Bilge/Assert.hs:109:19 in bilge-0.22.0-inplace:Bilge.Assert
          !!!, called at test/integration/API.hs:966:7 in main:API
        Use -p '!/RealAWS/&&/redis migration should work/' to rerun this test only.

it doesn't look related, but it's only happening on this branch, not on develop.

[...] it is not possible to create test users with shorter passwords anymore.

you could either call cassandra directly and inject the short password, or implement an /i/-endpoint that allows this. the former used to happen in the spar tests, but somebody removed it, so maybe we should aim for the second option.

let's pair on this on monday?

Comment on lines 350 to 352
type PlainTextPassword = PlainTextPassword' (6 :: Nat)

type PlainTextPasswordMinLength8 = PlainTextPassword' (8 :: Nat)
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
type PlainTextPassword = PlainTextPassword' (6 :: Nat)
type PlainTextPasswordMinLength8 = PlainTextPassword' (8 :: Nat)
type PlainTextPassword6 = PlainTextPassword' (6 :: Nat)
type PlainTextPassword = PlainTextPassword' (8 :: Nat)

The old passwords should have the more awkward name, the passwords we really want to deal with everywhere the simpler name.

Comment on lines 354 to 371
plainTextPasswordLegacy :: Text -> Maybe PlainTextPassword
plainTextPasswordLegacy = fmap PlainTextPassword' . checked

plainTextPasswordLegacyUnsafe :: Text -> PlainTextPassword
plainTextPasswordLegacyUnsafe = PlainTextPassword' . unsafeRange

plainTextPassword :: Text -> Maybe PlainTextPasswordMinLength8
plainTextPassword = fmap PlainTextPassword' . checked

plainTextPasswordUnsafe :: Text -> PlainTextPasswordMinLength8
plainTextPasswordUnsafe = PlainTextPassword' . unsafeRange

fromPlainTextPassword :: PlainTextPassword' t -> Text
fromPlainTextPassword = fromRange . fromPlainTextPassword'

-- | Convert a 'PlainTextPasswordMinLength8' to a legacy 'PlainTextPassword'.
toLegacy :: PlainTextPasswordMinLength8 -> PlainTextPassword
toLegacy = PlainTextPassword' . unsafeRange . fromPlainTextPassword
Copy link
Contributor

Choose a reason for hiding this comment

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

It's fine to use PlainTextPasswordLegacy instead of PlainTextPassword6, but please be consistent and name the constructors after the types they are constructing.


instance Arbitrary PlainTextPassword where
instance Arbitrary (PlainTextPassword' (8 :: Nat)) where
-- TODO: why 6..1024? For tests we might want invalid passwords as well, e.g. 3 chars
Copy link
Contributor

Choose a reason for hiding this comment

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

This TODO is obsolete: we don't have to test for errors that are caught by the type checker.

@fisx
Copy link
Contributor

fisx commented Mar 13, 2023

before b2adfe0:

$ make ci package=gundeck TASTY_PATTERN='!/RealAWS/&&/redis migration should work/'
[...]
Gundeck
  API tests
    Redis migration
      redis migration should work: 2023-03-13T10:01:10Z, D, Connecting to 127.0.0.1:9042
FAIL
        Exception: Error executing request: Safe.readNote no parse on "NO_HEADER_VALUE", unable to parse Location header
        CallStack (from HasCallStack):
          readNote, called at test/integration/API.hs:1253:7 in main:API
        CallStack (from HasCallStack):
          error, called at src/Bilge/Assert.hs:101:18 in bilge-0.22.0-inplace:Bilge.Assert
          <!!, called at src/Bilge/Assert.hs:109:19 in bilge-0.22.0-inplace:Bilge.Assert
          !!!, called at test/integration/API.hs:966:7 in main:API

1 out of 1 tests failed (0.07s)
[...]

after b2adfe0:

$ make ci package=gundeck TASTY_PATTERN='!/RealAWS/&&/redis migration should work/'
[...]
Gundeck
  API tests
    Redis migration
      redis migration should work: 2023-03-13T10:02:01Z, D, Connecting to 127.0.0.1:9042
OK (0.33s)

All 1 tests passed (0.35s)

I'd really like to know how this didn't trigger on CI or on your machine @battermann...

@fisx
Copy link
Contributor

fisx commented Mar 13, 2023

ah, maybe something to do with RealAWS?

fisx added 3 commits March 13, 2023 12:17
find services/ libs/ tools/ -name '*.hs' -exec perl -i -pe 's/\bPlainTextPassword\b([^'\''])/PlainTextPassword6\1/g' {} \;
find services/ libs/ tools/ -name '*.hs' -exec perl -i -pe 's/\bPlainTextPasswordMinLength8\b/PlainTextPassword8/g' {} \;
find services/ libs/ tools/ -name '*.hs' -exec perl -i -pe 's/\bplainTextPasswordLegacy\b/plainTextPassword6/g' {} \;
find services/ libs/ tools/ -name '*.hs' -exec perl -i -pe 's/\bplainTextPasswordLegacyUnsafe\b/plainTextPassword6Unsafe/g' {} \;
find services/ libs/ tools/ -name '*.hs' -exec perl -i -pe 's/\bplainTextPassword\b/plainTextPassword8/g' {} \;
find services/ libs/ tools/ -name '*.hs' -exec perl -i -pe 's/\bplainTextPasswordUnsafe\b/plainTextPassword8Unsafe/g' {} \;
find services/ libs/ tools/ -name '*.hs' -exec perl -i -pe 's/\btoLegacy\b/plainTextPassword8To6/g' {} \;
Copy link
Contributor

@fisx fisx left a comment

Choose a reason for hiding this comment

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

LGTM now! :)

please take a look at the changes (i think commit-by-commit is easiest, and you can ignore all the automatic renaming noise), and merge if you agree with everything.

@battermann
Copy link
Contributor Author

[...] it is not possible to create test users with shorter passwords anymore.

you could either call cassandra directly and inject the short password, or implement an /i/-endpoint that allows this. the former used to happen in the spar tests, but somebody removed it, so maybe we should aim for the second option.

let's pair on this on monday?

I added this test.

fisx and others added 10 commits March 15, 2023 10:49
* Downgrade to our fork of http2

It seems the released version of http2 is causing issues with streaming
of assets via federator.

* Add CHANGELOG entry
* Fix ES reset command in Makefile

* fixup! Fix ES reset command in Makefile
* Upgrade cachix to 1.3.1

* Trivial change to force rebuilding of haddocks
* Add `flakyTestCase` command and use it.

This should make life slightly more bearable for everybody including
concourse, while still allowing to run the pending tests locally by
setting `RUN_FLAKY_TESTS=1`.

* Make sanitize-pr faster by only looking at changed files.
lepsa and others added 7 commits March 15, 2023 10:39
…on (#3134)

* FS-1530: Allow partial success when removing users from conversations

* FS-1530 Adding tests for deleting conversations and removing members

* FS-1530 Formatting and hlint

* Hi CI

* HI CI

---------

Co-authored-by: Marko Dimjašević <marko.dimjasevic@wire.com>
Co-authored-by: Igor Ranieri <igor@elland.me>
…-to-enforce-stronger-password-restrictions-when-setting-a-password
@battermann battermann merged commit 1cb370d into develop Mar 15, 2023
@battermann battermann deleted the SQSERVICES-1931-wire-server-allow-backend-to-enforce-stronger-password-restrictions-when-setting-a-password branch March 15, 2023 15:59
lepsa pushed a commit to lepsa/wire-server that referenced this pull request Nov 28, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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.

8 participants

Comments