Communicating authentication data

In this section, "communication" is used in a broader sense, encompassing User Experience (UX) and client-server communication.

Not only is it true that "password entry should be obscured on user's screen" but also the "remember me functionality should be disabled".

You can accomplish both using an input field with type="password", and setting the autocomplete attribute to off1

<input type="password" name="passwd" autocomplete="off" />

Authentication credentials should be sent on HTTP POST requests only, using an encrypted connection (HTTPS). An exception to the encrypted connection may be the temporary passwords associated with email resets.

Although HTTP GET requests over TLS/SSL (HTTPS) look as secure as HTTP POST requests, remember that in general HTTP servers (eg. Apache2, Nginx3) do write the requested URL to the access log.

xxx.xxx.xxx.xxx - - [27/Feb/2017:01:55:09 +0000] "GET /?username=user&password=70pS3cure/oassw0rd HTTP/1.1" 200 235 "-" "Mozilla/5.0 (X11; Fedora; Linux x86_64; rv:51.0) Gecko/20100101 Firefox/51.0"

A well designed HTML form for authentication would look like:

<form method="post" action="https://somedomain.com/user/signin" autocomplete="off">
    <input type="hidden" name="csrf" value="CSRF-TOKEN" />

    <label>Username <input type="text" name="username" /></label>
    <label>Password <input type="password" name="password" /></label>

    <input type="submit" value="Submit" />
</form>

When handling authentication errors, your application should not disclose which part of the authentication data was incorrect. Instead of "Invalid username" or "Invalid password", just use "Invalid username and/or password" interchangeably:

<form method="post" action="https://somedomain.com/user/signin" autocomplete="off">
    <input type="hidden" name="csrf" value="CSRF-TOKEN" />

    <div class="error">
        <p>Invalid username and/or password</p>
    </div>

    <label>Username <input type="text" name="username" /></label>
    <label>Password <input type="password" name="password" /></label>

    <input type="submit" value="Submit" />
</form>

With a generic message you do not disclose:

  • Who is registered: "Invalid password" means that the username exists.
  • How your system works: "Invalid password" may reveal how your application works, first querying the database for the username and then comparing passwords in-memory

An example of how to perform authentication data validation (and storage) is available at Validation and Storage section.

After a successful login, the user should be informed about the last successful or unsuccessful access date/time so that he can detect and report suspicious activity. Further information regarding logging can be found in the Error Handling and Logging section of the document. Moreover, it is also recommended to use a constant time comparison function while checking passwords in order to prevent timing attack. The latter consists of analyzing the difference of time between multiple requests with different inputs. In this case, a standard comparison of the form record == password would return false at the first character that does not match. The closer the submitted password, the longer the response time. By exploiting that, an attacker could guess the password. Note that even if the record doesn't exist, we always force the execution of subtle.ConstantTimeCompare with an empty value to compare to the user input.


1. How to Turn Off Form Autocompletion, Mozilla Developer Network
2. Log Files, Apache Documentation
3. log_format, Nginx log_module "log_format" directive

results matching ""

    No results matching ""