Skip to content

Commit 162f167

Browse files
docs(auth): firm up password and token guidance
Replace tentative language with verified token-storage and validation behavior. Clarify the consequences of missing recoverable passwords, tighten the security impact statements, and correct password-length boundary wording. Signed-off-by: Josh <josh.t.richards@gmail.com>
1 parent 6e7082b commit 162f167

1 file changed

Lines changed: 77 additions & 65 deletions

File tree

‎admin_manual/installation/harden_server.rst‎

Lines changed: 77 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -19,86 +19,97 @@ Storage of account passwords
1919
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2020

2121
Nextcloud's built-in database user backend stores a salted, one-way hash of
22-
each account password. It prefers Argon2id when supported by the PHP
23-
installation, with Argon2i and bcrypt used as fallbacks. The algorithm, salt,
22+
each account password. It prefers Argon2id (when supported by the PHP
23+
installation), with Argon2i and bcrypt used as fallbacks. The algorithm, salt,
2424
and cost parameters are included in the stored hash. Existing hashes are
2525
automatically upgraded following successful password verification when they no
2626
longer match the preferred algorithm or parameters.
2727

2828
The hash is used to verify password-based login attempts and is not designed
29-
to be decrypted. When an external user backend such as LDAP is used, storage
29+
to be decrypted. When an external user backend (such as LDAP) is used, storage
3030
and verification of the account password are controlled by that backend.
3131

3232
This account-password hash is separate from any recoverable copy of the login
33-
password that Nextcloud may store in connection with authentication tokens, as
33+
password that Nextcloud stores in connection with authentication tokens, as
3434
described below.
3535

3636
Storage of authentication tokens
3737
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3838

3939
After successful authentication, Nextcloud issues an authentication token that
40-
clients use for subsequent authenticated requests. Depending on the token type
41-
and client, the token may be transmitted in a session cookie, used as an app
42-
password, or sent as a bearer token. Anyone who obtains a valid token may be
43-
able to authenticate as the associated user, subject to the token's scope,
44-
expiration, type, and server-side validity checks.
40+
the client presents with subsequent authenticated requests. A valid token can
41+
authenticate as the associated user, subject to the token's scope, expiration,
42+
type, and server-side validity checks. Depending on the token type and client,
43+
the token may be transmitted in a session cookie, used as an app password, or
44+
sent as a bearer token.
4545

4646
Nextcloud does not store the plaintext authentication token in the database.
4747
Instead, it stores a SHA-512 hash derived from the token and the
4848
instance-specific ``secret``. The corresponding server-side token record
4949
contains the associated user identity, authentication metadata, and
50-
cryptographic key material. Authentication tokens should therefore be
50+
cryptographic key material. Authentication tokens must therefore be
5151
protected like passwords. They should not be logged, placed in URLs, or
5252
intentionally persisted outside the client that uses them.
5353

5454
Token-associated storage of login passwords
5555
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5656

57-
By default, ``auth.storeCryptedPassword`` is enabled. When the plaintext login
58-
password is available to Nextcloud, Nextcloud may store a reversibly encrypted
59-
copy of it in the server-side records associated with the user's authentication
60-
tokens. Consequently, for an account using the built-in database user backend,
61-
the database may contain both the one-way account-password hash described above
62-
and one or more separately encrypted, recoverable copies of the same password.
63-
64-
The authentication token itself does not contain the login password. For each
65-
token record, Nextcloud generates a separate RSA key pair. The login password
66-
is encrypted with the record's public key, while the corresponding private key
67-
is encrypted using the authentication token together with the
68-
instance-specific ``secret`` from ``config.php``. The token and instance secret
69-
are therefore required to decrypt the password stored in that token record.
70-
71-
The recoverable copy is used by features that require the login credentials,
72-
such as connecting to external storage, configuring mail accounts, and
73-
periodically checking whether the password remains valid. It is not stored
74-
when no password or equivalent user secret is available, as can occur with
75-
some SSO or passwordless authentication flows. Existing token records can also
76-
remain without a stored password until Nextcloud receives the password during
77-
a later login or password update.
78-
79-
Administrators can disable this behavior with
80-
``auth.storeCryptedPassword``. Disabling it does not affect the one-way
81-
account-password hash used by the built-in user backend, but features that
82-
require recovery of the login password may no longer work. Password changes
83-
made directly in an external user backend might also no longer automatically
84-
invalidate connected clients.
57+
By default, ``auth.storeCryptedPassword`` is enabled. When this setting is
58+
enabled and the login password is available during token creation, Nextcloud
59+
stores a reversibly encrypted copy of it in the server-side
60+
authentication-token record.
61+
62+
For an account using the built-in database user backend, this encrypted copy is
63+
separate from the one-way account-password hash. The database contains the
64+
one-way account-password hash and also contains an encrypted password copy for
65+
each authentication-token record created with password storage enabled and a
66+
login password supplied.
67+
68+
The recoverable copy is used by features that need the original login
69+
credentials, such as connecting to external storage, autoconfiguring accounts
70+
in the Mail app, and periodically checking whether the login credentials
71+
remain valid. When token creation receives no login password, the resulting
72+
token record contains no recoverable password. Such a token record remains
73+
without a stored password until Nextcloud receives the password during a later
74+
login or password update.
75+
76+
The authentication token itself does not contain the login password. Each
77+
token record has a separate RSA key pair. Nextcloud encrypts the login password
78+
with the record's public key and encrypts the corresponding private key using
79+
the authentication token together with the instance-specific ``secret`` from
80+
``config.php``. Possession of the authentication token, instance secret, and
81+
corresponding database record is therefore sufficient to decrypt a password
82+
stored in that record.
83+
84+
Administrators can disable this behavior with ``auth.storeCryptedPassword``.
85+
Disabling it does not affect the one-way account-password hash used by the
86+
built-in database user backend. Features that rely on recovering the login
87+
password from an authenticate-token record cannot retrieve it from records
88+
created without a stored password.
89+
90+
When an authentication token contains a stored password, Nextcloud periodically
91+
checks that password against the user backend. If the password is no longer
92+
valid, Nextcloud marks the token as having an invalid password and rejects
93+
authentication with that token. When the token contains no stored password,
94+
Nextcloud skips this password check. Consequently, changing a password directly
95+
in an external user backend does not cause a token without a stored password
96+
to be rejected through the periodic credential check. The password change
97+
alone does not invalidate the token; the token remains valid until it expires,
98+
is otherwise invalidated, or the user is disabled.
8599

86100
Security consequences
87101
^^^^^^^^^^^^^^^^^^^^^
88102

89-
Leakage of authentication data can have negative security consequences. The
90-
impact depends on the data and capabilities available to the actor:
103+
Leakage of authentication data has the following security consequences:
91104

92-
- An actor with access to only a valid authentication token can generally
93-
impersonate the associated user wherever that token is accepted. Access may
94-
be limited by the token's scope, expiration, type, and other validity checks.
95-
- An actor with access to an authentication token, the instance-specific
96-
``secret`` from ``config.php``, and the corresponding database record may be
97-
able to decrypt the login password stored in that record, if recoverable
98-
password storage was enabled and the password was available to Nextcloud.
99-
- Access to the one-way account-password hash alone does not provide a direct
100-
way to recover the password. However, password hashes must still be protected
101-
against offline password-guessing attacks.
105+
- An actor with a valid authentication token can authenticate as the associated
106+
user, subject to the token's scope, expiration, type, and server-side validity
107+
checks.
108+
- An actor with the authentication token, the instance-specific ``secret`` from
109+
``config.php``, and the corresponding database record can decrypt the login
110+
password stored in that record.
111+
- An account-password hash does not reveal the original password directly, but
112+
an actor who obtains it can perform offline password-guessing attacks.
102113

103114
.. _password_length_limits:
104115

@@ -109,35 +120,36 @@ Nextcloud accepts account passwords of up to 469 bytes through its standard
109120
account-creation, password-change, and password-reset interfaces. This is the
110121
maximum account-password length enforced by these interfaces. Because the
111122
limit is measured in bytes, a password containing multibyte characters (such as
112-
emojis or characters from non-Latin scripts) may reach the limit with fewer than
113-
469 characters.
123+
emojis or characters from non-Latin scripts) can reach the limit with fewer
124+
than 469 characters.
114125

115-
Administrators can use the :doc:`Password Policy app </configuration_user/user_password_policy>`
116-
to configure requirements such as a minimum password length and other
117-
complexity rules. External user backends may impose additional or different
118-
requirements.
126+
Administrators can use the
127+
:doc:`Password Policy app </configuration_user/user_password_policy>` to
128+
configure requirements such as a minimum password length and other complexity
129+
rules. External user backends can impose additional or different requirements.
119130

120-
The following implementation details do not reduce the general password limits,
121-
but they are relevant when selecting a password policy:
131+
The following implementation details do not change the 469-byte
132+
account-password maximum, but are relevant when selecting a password policy:
122133

123134
Token Encryption Performance
124135
When ``auth.storeCryptedPassword`` is enabled and an account password is
125136
longer than 214 bytes, Nextcloud uses a larger RSA key when creating
126137
authentication-token records. This increases token-generation overhead, but
127-
does not prevent passwords between 214 and 469 bytes from being accepted.
138+
does not prevent passwords between 215 and 469 bytes from being accepted.
128139
The 214-byte threshold is therefore a performance consideration, not a
129140
password-length limit.
130141

131142
Administrators who expect very long or one-time passwords to be used may
132143
consider disabling ``auth.storeCryptedPassword`` to avoid this overhead,
133144
subject to the functional consequences described above.
134145

135-
Algorithmic Truncation (Bcrypt)
136-
Nextcloud prefers Argon2id for one-way password hashing when it is supported
137-
by PHP, with Argon2i and bcrypt as fallbacks. Bcrypt considers only the first
138-
72 bytes of its input. Therefore, if bcrypt is selected, input after the
139-
first 72 bytes does not contribute to password verification. This is a
140-
bcrypt-specific behavior, not a general 72-byte limit imposed by Nextcloud.
146+
Algorithmic Truncation (bcrypt fallback)
147+
Nextcloud prefers Argon2id for one-way password hashing (when supported
148+
by the PHP installation), with Argon2i and bcrypt as fallbacks. Bcrypt
149+
considers only the first 72 bytes of its input. Therefore, if bcrypt is
150+
selected, input after the first 72 bytes does not contribute to password
151+
verification. This is a bcrypt-specific behavior, not a general 72-byte
152+
limit imposed by Nextcloud.
141153

142154
Passwords protecting public link and mail shares use the same one-way password
143155
hasher and are subject to the applicable share-password policy. They are not

0 commit comments

Comments
 (0)