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

MSC2000: Server-side password policies #2000

Closed
wants to merge 9 commits into from

Conversation

babolivier
Copy link
Contributor

@babolivier babolivier added proposal-in-review proposal A matrix spec change proposal labels May 15, 2019
@lampholder
Copy link
Member

I HAVE OPINIONS 😁

We want our users to have a good experience and strong passwords

A good UX means:

  • you know what the password requirements are up front
  • you get good, quick feedback (in your own language) to make it easy to select a strong password
  • the client must never tell you that your password is good only for it to be rejected by the server

Strong passwords means:

  • mathematically difficult for a computer to guess

My thoughts

I'm nervous about our programatically describing password complexity requirements. Over time, as new requirements arrive (no repeated alphabetical/keyboard layout sequences, none of your past three passwords, no passwords with the current date in them, etc.) this will be harder and harder to describe in a password complexity DSL that then has to be interpretted in the same way across all clients. For this reason, I would rather all password validation happen server side.

We could support server side password complexity validation by exposing an additional API, to which you can submit a password and it will respond with feedback. This feedback could take the form of:

{
    "acceptable_password": false,
    "feedback": [
        {
            "code": "E_KEYBOARD_SEQUENCE",
            "description": "Straight rows of keys are easy to guess"
        },
        ...
    ]
}

Then the new password complexity route, GET /_matrix/client/r0/password_policy, could return something like:

{
    "policy": "namespaced.policy.name",
    "description": "I am a string containing a prose description of the password complexity"
}

How to provide decent internatioionalisation of ^ is an outstanding issue.

The existing password setting/resetting endpoints could still reply with the specced weak password error code, but would ideally also include the same password complexity feedback warnings from the complexity validation API.

@babolivier
Copy link
Contributor Author

IRL chat concluded on that I'll update the proposal so that it keeps parameters in the response for /password_policy but defines mode precise error codes so that the client can handle both display and l18n on both ends.

@turt2live turt2live changed the title Proposal for server-side password policies MSC2000: Server-side password policies May 15, 2019
Copy link
Member

@turt2live turt2live left a comment

Choose a reason for hiding this comment

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

mostly have comments on structure - the concept is a great addition!

proposals/2000-password-policies.md Show resolved Hide resolved
proposals/2000-password-policies.md Outdated Show resolved Hide resolved
proposals/2000-password-policies.md Outdated Show resolved Hide resolved
proposals/2000-password-policies.md Outdated Show resolved Hide resolved
proposals/2000-password-policies.md Outdated Show resolved Hide resolved
@joepie91
Copy link

* you know what the password requirements are up front

I think this objective is mutually exclusive with actual password strength. Pretty much every password policy that's sufficiently easy for the average user to understand in prose, is going to be insufficiently accurate in terms of guaranteeing a minimum password complexity. See also zxcvbn, which is mentioned in the MSC.

I'm also not sure that there's an inherent benefit in the requirements being known upfront, so long as the complexity feedback is easily understandable and actionable.

@nadonomy
Copy link

I'm also not sure that there's an inherent benefit in the requirements being known upfront, so long as the complexity feedback is easily understandable and actionable.

From doing UX research in person— I've witnessed non-technical users struggle when they can't conceptualise the password they want to use before typing it, leading to painful guessing games. Similarly, I've seen the same frustrations from technical folk using generated passwords from password managers.

@joepie91
Copy link

From doing UX research in person— I've witnessed non-technical users struggle when they can't conceptualise the password they want to use before typing it, leading to painful guessing games. Similarly, I've seen the same frustrations from technical folk using generated passwords from password managers.

This sounds very much based on experiences with arbitrary-password-rule-based systems (as opposed to complexity analysis, like what zxcvbn does), and half the reason for existence of zxcvbn is to prevent the situation where people are told a password is 'bad' for arbitrary reasons.

Do your observations hold up as well in a scenario where the password quality checker doesn't over-catch, and thus the user is only told that a password is bad when it really is obviously bad?

(I'm particularly wondering in the context of password manager usage, because zxcvbn basically never turns down a password from a password generator, given that they are inherently random.)

@nadonomy
Copy link

From doing UX research in person— I've witnessed non-technical users struggle when they can't conceptualise the password they want to use before typing it, leading to painful guessing games. Similarly, I've seen the same frustrations from technical folk using generated passwords from password managers.

This sounds very much based on experiences with arbitrary-password-rule-based systems (as opposed to complexity analysis, like what zxcvbn does), and half the reason for existence of zxcvbn is to prevent the situation where people are told a password is 'bad' for arbitrary reasons.

Do your observations hold up as well in a scenario where the password quality checker doesn't over-catch, and thus the user is only told that a password is bad when it really is obviously bad?

(I'm particularly wondering in the context of password manager usage, because zxcvbn basically never turns down a password from a password generator, given that they are inherently random.)

Yes. More-so, 'over-catching' and 'obviously bad' have a countless number of definitions to different developers and users. For some users all password rules are arbitrary, especially as the industry and user expectations move towards biometric authentication.

The reality is this proposal should support the Matrix ecosystem, with whatever password policies & UX Matrix developers want to implement for their users. Intentions and use cases could vary wildly, and in at least one client (Riot Web) we have a requirement to display some password requirements up front.

@babolivier
Copy link
Contributor Author

I've incorporated most of the review comments minus one about which I have expressed a question here.

server requires at least one.
* `M_PASSWORD_IN_DICTIONARY`: the password was found in a dictionary, and is
not acceptable.
* `M_WEAK_PASSWORD` if the reason the password has been refused doesn't fall
Copy link
Member

Choose a reason for hiding this comment

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

Note that this is already a thing in the spec

.. WARNING::
  Clients SHOULD enforce that the password provided is suitably complex. The
  password SHOULD include a lower-case letter, an upper-case letter, a number
  and a symbol and be at a minimum 8 characters in length. Servers MAY reject
  weak passwords with an error code ``M_WEAK_PASSWORD``.

Copy link
Member

Choose a reason for hiding this comment

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

Maybe instead of adding new error codes, we can just stick with M_WEAK_PASSWORD as the error code, and add a new field (say, reason?) to the response that describes why the password is too week. We could make this field an array, so that it can return multiple reasons (e.g. password is too short and has no symbol)

Copy link
Member

Choose a reason for hiding this comment

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

After some of the discussion in #matrix-spec, I'm inclined to agree. It's likely that we won't have a single error code to point to, and will need an array. M_WEAK_PASSWORD with a reasons array does make sense.

@lampholder
Copy link
Member

I'm starting to think that this might not be worth speccing now.

It's true that server side password complexity is likely to be a desirable feature. However, if I understand correctly, it is fundamental incompatible with our desired direction cryptographic authentication (in which the server has no visibility on passwords), so we might be best off special-casing solutions for now and thinking about how crypto-auth and (likely corporate) password complexity policies can live together at a later date.

What do people think?

clokep added a commit to matrix-org/synapse that referenced this pull request May 19, 2020
Synapse 1.13.0 (2020-05-19)
===========================

This release brings some potential changes necessary for certain
configurations of Synapse:

* If your Synapse is configured to use SSO and have a custom
  `sso_redirect_confirm_template_dir` configuration option set, you will need
  to duplicate the new `sso_auth_confirm.html`, `sso_auth_success.html` and
  `sso_account_deactivated.html` templates into that directory.
* Synapse plugins using the `complete_sso_login` method of
  `synapse.module_api.ModuleApi` should instead switch to the async/await
  version, `complete_sso_login_async`, which includes additional checks. The
  former version is now deprecated.
* A bug was introduced in Synapse 1.4.0 which could cause the room directory
  to be incomplete or empty if Synapse was upgraded directly from v1.2.1 or
  earlier, to versions between v1.4.0 and v1.12.x.

Please review [UPGRADE.rst](https://github.com/matrix-org/synapse/blob/master/UPGRADE.rst)
for more details on these changes and for general upgrade guidance.

Notice of change to the default `git` branch for Synapse
--------------------------------------------------------

With the release of Synapse 1.13.0, the default `git` branch for Synapse has
changed to `develop`, which is the development tip. This is more consistent with
common practice and modern `git` usage.

The `master` branch, which tracks the latest release, is still available. It is
recommended that developers and distributors who have scripts which run builds
using the default branch of Synapse should therefore consider pinning their
scripts to `master`.

Features
--------

- Extend the `web_client_location` option to accept an absolute URL to use as a redirect. Adds a warning when running the web client on the same hostname as homeserver. Contributed by Martin Milata. ([\#7006](#7006))
- Set `Referrer-Policy` header to `no-referrer` on media downloads. ([\#7009](#7009))
- Add support for running replication over Redis when using workers. ([\#7040](#7040), [\#7325](#7325), [\#7352](#7352), [\#7401](#7401), [\#7427](#7427), [\#7439](#7439), [\#7446](#7446), [\#7450](#7450), [\#7454](#7454))
- Admin API `POST /_synapse/admin/v1/join/<roomIdOrAlias>` to join users to a room like `auto_join_rooms` for creation of users. ([\#7051](#7051))
- Add options to prevent users from changing their profile or associated 3PIDs. ([\#7096](#7096))
- Support SSO in the user interactive authentication workflow. ([\#7102](#7102), [\#7186](#7186), [\#7279](#7279), [\#7343](#7343))
- Allow server admins to define and enforce a password policy ([MSC2000](matrix-org/matrix-spec-proposals#2000)). ([\#7118](#7118))
- Improve the support for SSO authentication on the login fallback page. ([\#7152](#7152), [\#7235](#7235))
- Always whitelist the login fallback in the SSO configuration if `public_baseurl` is set. ([\#7153](#7153))
- Admin users are no longer required to be in a room to create an alias for it. ([\#7191](#7191))
- Require admin privileges to enable room encryption by default. This does not affect existing rooms. ([\#7230](#7230))
- Add a config option for specifying the value of the Accept-Language HTTP header when generating URL previews. ([\#7265](#7265))
- Allow `/requestToken` endpoints to hide the existence (or lack thereof) of 3PID associations on the homeserver. ([\#7315](#7315))
- Add a configuration setting to tweak the threshold for dummy events. ([\#7422](#7422))

Bugfixes
--------

- Don't attempt to use an invalid sqlite config if no database configuration is provided. Contributed by @nekatak. ([\#6573](#6573))
- Fix single-sign on with CAS systems: pass the same service URL when requesting the CAS ticket and when calling the `proxyValidate` URL. Contributed by @Naugrimm. ([\#6634](#6634))
- Fix missing field `default` when fetching user-defined push rules. ([\#6639](#6639))
- Improve error responses when accessing remote public room lists. ([\#6899](#6899), [\#7368](#7368))
- Transfer alias mappings on room upgrade. ([\#6946](#6946))
- Ensure that a user interactive authentication session is tied to a single request. ([\#7068](#7068), [\#7455](#7455))
- Fix a bug in the federation API which could cause occasional "Failed to get PDU" errors. ([\#7089](#7089))
- Return the proper error (`M_BAD_ALIAS`) when a non-existant canonical alias is provided. ([\#7109](#7109))
- Fix a bug which meant that groups updates were not correctly replicated between workers. ([\#7117](#7117))
- Fix starting workers when federation sending not split out. ([\#7133](#7133))
- Ensure `is_verified` is a boolean in responses to `GET /_matrix/client/r0/room_keys/keys`. Also warn the user if they forgot the `version` query param. ([\#7150](#7150))
- Fix error page being shown when a custom SAML handler attempted to redirect when processing an auth response. ([\#7151](#7151))
- Avoid importing `sqlite3` when using the postgres backend. Contributed by David Vo. ([\#7155](#7155))
- Fix excessive CPU usage by `prune_old_outbound_device_pokes` job. ([\#7159](#7159))
- Fix a bug which could cause outbound federation traffic to stop working if a client uploaded an incorrect e2e device signature. ([\#7177](#7177))
- Fix a bug which could cause incorrect 'cyclic dependency' error. ([\#7178](#7178))
- Fix a bug that could cause a user to be invited to a server notices (aka System Alerts) room without any notice being sent. ([\#7199](#7199))
- Fix some worker-mode replication handling not being correctly recorded in CPU usage stats. ([\#7203](#7203))
- Do not allow a deactivated user to login via SSO. ([\#7240](#7240), [\#7259](#7259))
- Fix --help command-line argument. ([\#7249](#7249))
- Fix room publish permissions not being checked on room creation. ([\#7260](#7260))
- Reject unknown session IDs during user interactive authentication instead of silently creating a new session. ([\#7268](#7268))
- Fix a SQL query introduced in Synapse 1.12.0 which could cause large amounts of logging to the postgres slow-query log. ([\#7274](#7274))
- Persist user interactive authentication sessions across workers and Synapse restarts. ([\#7302](#7302))
- Fixed backwards compatibility logic of the first value of `trusted_third_party_id_servers` being used for `account_threepid_delegates.email`, which occurs when the former, deprecated option is set and the latter is not. ([\#7316](#7316))
- Fix a bug where event updates might not be sent over replication to worker processes after the stream falls behind. ([\#7337](#7337), [\#7358](#7358))
- Fix bad error handling that would cause Synapse to crash if it's provided with a YAML configuration file that's either empty or doesn't parse into a key-value map. ([\#7341](#7341))
- Fix incorrect metrics reporting for `renew_attestations` background task. ([\#7344](#7344))
- Prevent non-federating rooms from appearing in responses to federated `POST /publicRoom` requests when a filter was included. ([\#7367](#7367))
- Fix a bug which would cause the room durectory to be incorrectly populated if Synapse was upgraded directly from v1.2.1 or earlier to v1.4.0 or later. Note that this fix does not apply retrospectively; see the [upgrade notes](UPGRADE.rst#upgrading-to-v1130) for more information. ([\#7387](#7387))
- Fix bug in `EventContext.deserialize`. ([\#7393](#7393))
- Fix a long-standing bug which could cause messages not to be sent over federation, when state events with state keys matching user IDs (such as custom user statuses) were received. ([\#7376](#7376))
- Restore compatibility with non-compliant clients during the user interactive authentication process, fixing a problem introduced in v1.13.0rc1. ([\#7483](#7483))
- Hash passwords as early as possible during registration. ([\#7523](#7523))

Improved Documentation
----------------------

- Update Debian installation instructions to recommend installing the `virtualenv` package instead of `python3-virtualenv`. ([\#6892](#6892))
- Improve the documentation for database configuration. ([\#6988](#6988))
- Improve the documentation of application service configuration files. ([\#7091](#7091))
- Update pre-built package name for FreeBSD. ([\#7107](#7107))
- Update postgres docs with login troubleshooting information. ([\#7119](#7119))
- Clean up INSTALL.md a bit. ([\#7141](#7141))
- Add documentation for running a local CAS server for testing. ([\#7147](#7147))
- Improve README.md by being explicit about public IP recommendation for TURN relaying. ([\#7167](#7167))
- Fix a small typo in the `metrics_flags` config option. ([\#7171](#7171))
- Update the contributed documentation on managing synapse workers with systemd, and bring it into the core distribution. ([\#7234](#7234))
- Add documentation to the `password_providers` config option. Add known password provider implementations to docs. ([\#7238](#7238), [\#7248](#7248))
- Modify suggested nginx reverse proxy configuration to match Synapse's default file upload size. Contributed by @ProCycleDev. ([\#7251](#7251))
- Documentation of media_storage_providers options updated to avoid misunderstandings. Contributed by Tristan Lins. ([\#7272](#7272))
- Add documentation on monitoring workers with Prometheus. ([\#7357](#7357))
- Clarify endpoint usage in the users admin api documentation. ([\#7361](#7361))

Deprecations and Removals
-------------------------

- Remove nonfunctional `captcha_bypass_secret` option from `homeserver.yaml`. ([\#7137](#7137))

Internal Changes
----------------

- Add benchmarks for LruCache. ([\#6446](#6446))
- Return total number of users and profile attributes in admin users endpoint. Contributed by Awesome Technologies Innovationslabor GmbH. ([\#6881](#6881))
- Change device list streams to have one row per ID. ([\#7010](#7010))
- Remove concept of a non-limited stream. ([\#7011](#7011))
- Move catchup of replication streams logic to worker. ([\#7024](#7024), [\#7195](#7195), [\#7226](#7226), [\#7239](#7239), [\#7286](#7286), [\#7290](#7290), [\#7318](#7318), [\#7326](#7326), [\#7378](#7378), [\#7421](#7421))
- Convert some of synapse.rest.media to async/await. ([\#7110](#7110), [\#7184](#7184), [\#7241](#7241))
- De-duplicate / remove unused REST code for login and auth. ([\#7115](#7115))
- Convert `*StreamRow` classes to inner classes. ([\#7116](#7116))
- Clean up some LoggingContext code. ([\#7120](#7120), [\#7181](#7181), [\#7183](#7183), [\#7408](#7408), [\#7426](#7426))
- Add explicit `instance_id` for USER_SYNC commands and remove implicit `conn_id` usage. ([\#7128](#7128))
- Refactored the CAS authentication logic to a separate class. ([\#7136](#7136))
- Run replication streamers on workers. ([\#7146](#7146))
- Add tests for outbound device pokes. ([\#7157](#7157))
- Fix device list update stream ids going backward. ([\#7158](#7158))
- Use `stream.current_token()` and remove `stream_positions()`. ([\#7172](#7172))
- Move client command handling out of TCP protocol. ([\#7185](#7185))
- Move server command handling out of TCP protocol. ([\#7187](#7187))
- Fix consistency of HTTP status codes reported in log lines. ([\#7188](#7188))
- Only run one background database update at a time. ([\#7190](#7190))
- Remove sent outbound device list pokes from the database. ([\#7192](#7192))
- Add a background database update job to clear out duplicate `device_lists_outbound_pokes`. ([\#7193](#7193))
- Remove some extraneous debugging log lines. ([\#7207](#7207))
- Add explicit Python build tooling as dependencies for the snapcraft build. ([\#7213](#7213))
- Add typing information to federation server code. ([\#7219](#7219))
- Extend room admin api (`GET /_synapse/admin/v1/rooms`) with additional attributes. ([\#7225](#7225))
- Unblacklist '/upgrade creates a new room' sytest for workers. ([\#7228](#7228))
- Remove redundant checks on `daemonize` from synctl. ([\#7233](#7233))
- Upgrade jQuery to v3.4.1 on fallback login/registration pages. ([\#7236](#7236))
- Change log line that told user to implement onLogin/onRegister fallback js functions to a warning, instead of an info, so it's more visible. ([\#7237](#7237))
- Correct the parameters of a test fixture. Contributed by Isaiah Singletary. ([\#7243](#7243))
- Convert auth handler to async/await. ([\#7261](#7261))
- Add some unit tests for replication. ([\#7278](#7278))
- Improve typing annotations in `synapse.replication.tcp.streams.Stream`. ([\#7291](#7291))
- Reduce log verbosity of url cache cleanup tasks. ([\#7295](#7295))
- Fix sample SAML Service Provider configuration. Contributed by @frcl. ([\#7300](#7300))
- Fix StreamChangeCache to work with multiple entities changing on the same stream id. ([\#7303](#7303))
- Fix an incorrect import in IdentityHandler. ([\#7319](#7319))
- Reduce logging verbosity for successful federation requests. ([\#7321](#7321))
- Convert some federation handler code to async/await. ([\#7338](#7338))
- Fix collation for postgres for unit tests. ([\#7359](#7359))
- Convert RegistrationWorkerStore.is_server_admin and dependent code to async/await. ([\#7363](#7363))
- Add an `instance_name` to `RDATA` and `POSITION` replication commands. ([\#7364](#7364))
- Thread through instance name to replication client. ([\#7369](#7369))
- Convert synapse.server_notices to async/await. ([\#7394](#7394))
- Convert synapse.notifier to async/await. ([\#7395](#7395))
- Fix issues with the Python package manifest. ([\#7404](#7404))
- Prevent methods in `synapse.handlers.auth` from polling the homeserver config every request. ([\#7420](#7420))
- Speed up fetching device lists changes when handling `/sync` requests. ([\#7423](#7423))
- Run group attestation renewal in series rather than parallel for performance. ([\#7442](#7442))
- Fix linting errors in new version of Flake8. ([\#7470](#7470))
- Update the version of dh-virtualenv we use to build debs, and add focal to the list of target distributions. ([\#7526](#7526))
@grinapo
Copy link
Contributor

grinapo commented May 19, 2020

All people who still believe the 2003 Curse of Bill Burr (advising using a password hard for humans and easy for computers) shall familiarise themselves with NIST Special Publication 800-63B, especially section 5.1.1, 5.1.1.2 which describe what good and bad practices are there, and what ought to be followed and what avoided.

Basically minimum_length is great. All other fixed checks are bad practices.
Other good practices include the mentioned zxcvbn (and similar pssword strength indicators) along with forbidden words and patterns (common dictionary words etc.), telling the user the requirements and reasons of failure, among other things, I don't want to repeat or summarize the 800-63B unless requested.

It is not forbidden to implement bad practices but they clearly shall be labeled as such.

@turt2live turt2live added the needs-implementation This MSC does not have a qualifying implementation for the SCT to review. The MSC cannot enter FCP. label Jun 8, 2021
NicolaiSoeborg added a commit to NicolaiSoeborg/matrix-spec that referenced this pull request Sep 15, 2022
A strong password is not necessary complex (https://xkcd.com/936/). Having arbitrary password requirements is a bit of a pain - we should rather push for 2FA / passwordless auth. 

I don't think this is a breaking change as it only change a "SHOULD" sentence. Any mismatch between clients / servers should still be 'spec complient' within the old text.

ECP = Enforce Complex Password
Client ECP - Server ECP: ✅
Client ECP - Server not-ECP: ✅
Client not-ECP - Server not-ECP: ✅
Client not-ECP - Server ECP: Potentially `M_WEAK_PASSWORD` which the client should already be able to handle.

This change will probably make it easier to implement [MSC2000](matrix-org/matrix-spec-proposals#2000)
@babolivier
Copy link
Contributor Author

This proposal has bitrotten for a while now, and it seems clear that it isn't the correct way to fix this problem. Moreover, I am not likely to be caring after it any more, so I'm closing it.

@babolivier babolivier closed this Feb 20, 2023
@turt2live turt2live added the abandoned A proposal where the author/shepherd is not responsive label Feb 20, 2023
@ptman
Copy link
Contributor

ptman commented Feb 27, 2023

The server caring about password policies should probably be the OpenIDC identity provider. https://areweoidcyet.com/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
abandoned A proposal where the author/shepherd is not responsive kind:feature MSC for not-core and not-maintenance stuff needs-implementation This MSC does not have a qualifying implementation for the SCT to review. The MSC cannot enter FCP. proposal A matrix spec change proposal
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants