Authentication verification requirements

ASVS Verification Requirement

ID Detailed Verification Requirement Level 1 Level 2 Level 3 Since
2.1 Verify all pages and resources by default require authentication except those specifically intended to be public (Principle of complete mediation). x x x 1.0
2.2 Verify that forms containing credentials are not filled in by the application. Pre-filling by the application implies that credentials are stored in plaintext or a reversible format, which is explicitly prohibited. x x x 3.0.1
2.4 Verify all authentication controls are enforced on the server side. x x x 1.0
2.6 Verify all authentication controls fail securely to ensure attackers cannot log in. x x x 1.0
2.7 Verify password entry fields allow, or encourage, the use of passphrases, and do not prevent password managers, long passphrases or highly complex passwords being entered. x x x 3.0
2.8 Verify all account identity authentication functions (such as update profile, forgot password, disabled / lost token, help desk or IVR) that might regain access to the account are at least as resistant to attack as the primary authentication mechanism. x x x 2.0
2.9 Verify that the changing password functionality includes the old password, the new password, and a password confirmation. x x x 1.0
2.12 Verify that all authentication decisions can be logged, without storing sensitive session identifiers or passwords. This should include requests with relevant metadata needed for security investigations.   x x 3.0.1
2.13 Verify that account passwords are one way hashed with a salt, and there is sufficient work factor to defeat brute force and password hash recovery attacks.   x x 3.0.1
2.16 Verify that credentials are transported using a suitable encrypted link and that all pages/functions that require a user to enter credentials are done so using an encrypted link. x x x 3.0
2.17 Verify that the forgotten password function and other recovery paths do not reveal the current password and that the new password is not sent in clear text to the user. x x x 2.0
2.18 Verify that information enumeration is not possible via login, password reset, or forgot account functionality. x x x 2.0
2.19 Verify there are no default passwords in use for the application framework or any components used by the application (such as “admin/password”). x x x 2.0
2.20 Verify that anti-automation is in place to prevent breached credential testing, brute forcing, and account lockout attacks. x x x 3.0.1
2.21 Verify that all authentication credentials for accessing services external to the application are encrypted and stored in a protected location.   x x 2.0
2.22 Verify that forgotten password and other recovery paths use a TOTP or other soft token, mobile push, or other offline recovery mechanism. Use of a random value in an e-mail or SMS should be a last resort and is known weak. x x x 3.0.1
2.23 Verify that account lockout is divided into soft and hard lock status, and these are not mutually exclusive. If an account is temporarily soft locked out due to a brute force attack, this should not reset the hard lock status.   x x 3.0
2.24 Verify that if shared knowledge based questions (also known as ““secret questions””) are required, the questions do not violate privacy laws and are sufficiently strong to protect accounts from malicious recovery. x x x 3.0.1
2.25 Verify that the system can be configured to disallow the use of a configurable number of previous passwords.   x x 2.0
2.26 Verify that risk based re-authentication, two factor or transaction signing is in place for high value transactions.   x x 3.0.1
2.27 Verify that measures are in place to block the use of commonly chosen passwords and weak passphrases. x x x 3.0
2.28 Verify that all authentication challenges, whether successful or failed, should respond in the same average response time.     x 3.0
2.29 Verify that secrets, API keys, and passwords are not included in the source code, or online source code repositories.     x 3.0
2.30 Verify that if an application allows users to authenticate, they use a proven secure authentication mechanism. x x x 3.0
2.31 Verify that if an application allows users to authenticate, they can authenticate using two-factor authentication or other strong authentication, or any similar scheme that provides protection against username + password disclosure.   x x 3.0
2.32 Verify that administrative interfaces are not accessible to untrusted parties x x x 3.0
2.33 Browser autocomplete, and integration with password managers are permitted unless prohibited by risk based policy. x x x 3.0.1


There is only a very limited amount of public endpoints. All the others require authentication.

Endpoint Usecase
info/ First call in the login process to authenticate the server
healthcheck/ Healthcheck endpoint
password/ Password reset with a password recovery key
authentication/register/ Registration endpoint
authentication/verify-email/ Email Verification endpoint to validate email ownership
authentication/login/ Second call in the login process to authenticate the user


Not applicable to Psono, as Psono as a password manager has the sole purpose of “filling passwords in password fields”.


See V2.1 for a list of endpoints that are public available. Unittest coverage ensure proper access controls to ressources behind endpoints (e.g. access rights to a share).


Unittest coverage ensure proper access controls to ressources behind endpoints (e.g. access rights to a share).


There is no length restriction on password fields.


The form in the client has the old password, new password and new password confirmation field. The API endpoint user/update/ validates the old authkey derived from the old password.


Part of the Psono Enterprise Edition.


This is a two step process. First there is only an authkey, that is sent to the server, that is derived from the username as salt and the password (see below for implementation details).

var generate_authkey = function (username, password) {

    var salt = sha512(username.toLowerCase());

    var u = 14; // 2^14 = 16MB
    var r = 8;
    var p = 1;
    var l = 64; // 64 Bytes = 512 Bits

    var authkey = to_hex(scrypt(encode_utf8(password), salt, u, r, p, l));

    return authkey;

The storage on the server for validation is using Django’s BCryptSHA256PasswordHasher that is using bcrypt of the sha256 hash of the authkey and 12 rounds.


class BCryptSHA256PasswordHasher(BasePasswordHasher):
    Secure password hashing using the bcrypt algorithm (recommended)
    This is considered by many to be the most secure algorithm but you
    must first install the bcrypt library.  Please be warned that
    this library depends on native C code and might cause portability
    algorithm = "bcrypt_sha256"
    digest = hashlib.sha256
    library = ("bcrypt", "bcrypt")
    rounds = 12

    def salt(self):
        bcrypt = self._load_library()
        return bcrypt.gensalt(self.rounds)

    def encode(self, password, salt):
        bcrypt = self._load_library()
        password = password.encode()
        # Hash the password prior to using bcrypt to prevent password
        # truncation as described in #20138.
        if self.digest is not None:
            # Use binascii.hexlify() because a hex encoded bytestring is str.
            password = binascii.hexlify(self.digest(password).digest())

        data = bcrypt.hashpw(password, salt)
        return "%s$%s" % (self.algorithm, data.decode('ascii'))


Psonos implementation consists of three layers tackling this requirement.

  • First the password is only sent as a very secure hash to the server.
  • Second all communication to the server is protected by SSL.
  • Third all communication is encapsulated in Psonos Transport Encryption Layer.


The recovery code mechanism offered by Psono does not contain the old password, as its just an ID and a secret to decrypt the recovery secrets stored on the server. The recovery secrets are the users encrypted private and secret key. During the process the user provides the new password, which is then used to reencrypt the private and secret key, while profing to the server cryptographically the posession of the secret, that was used to decrypt the recovery secrets.


Login and password recovery function (like all endpoints) have a rate limit.


Psono itself does not generate a default user / password. Applications that relies on to work have been verified to not use any “default” passwords.


All endpoints are secured with rate limiting. The block is not account based, so account lockout attacks are not applicable.


Currently credentials to external applications are stored unencrypted on the disc in a config file mitigating the risk due to SQL injection. The application allows administrators to encrypt the disc, as long as the encryption is transparent for the application. runs on GCP and all discs there are encrypted automatically by Google.


No random value is sent (via email nor SMS). The recovery code is advised to be printed out and therefore fulfills the “other offline recovery mechanism” phrase.


Accounts do not yet get locked, therefore no need to differentiate between hard and soft locked state


No shared knowledge based questions required.


Possible with the DISABLE_LAST_PASSWORDS settings parameter, allowing to block the last X passwords.


Some key functions that are dangerous require, that the user provides his password again. e.g.:

  • Deletion of a complete datastore
  • Password change


Psono offers guidance to users by showing a password strength meter to helper users to choose a good password. The strength meter drops to zero if it recognizes weak parts in the password. Due to the implementation that not the actual password is sent to the server, all restrictions on a password can only applied on the client and in the end cannot be enforced. The current password restriction only demands 12 digits and does not impose any composition rules according to the NIST guideline ( Section

V2.28 (violation)

Very hard to implement and therefore not implemented.


Only the server is in possession of secrets and all of them are in the settings.yaml which is not part of the source code or any online source code repository.


The only application allowing users to authenticate is LDAP, which is part of the Enterprise Edition. LDAP is currently not used by but if used by third parties, its their responsibility to use LDAPS, which is a proven secure authentication mechanism.


The combination of LDAP and Psono two factor authentication is possible.


Psono offers the possibility to disable admin endpoints on public accessible servers and create specific servers inside of a secure network perimeter. As an alternative the reverse proxy can be configured to allow only access to the admin/ endpoint from specific IPs. The admin client that uses those endpoint to administrate Psono pose no threat and can also be hosted behind the firewall, public or with an IP whitelisting on the reverse proxy.


Psono itself (even if not recommended) is not blocking (or imposing any limits) on the use of another password manager.

Edit me