Friday, February 9, 2018

Testing the Login Screen

The login screen is the first line of defense between your application and a malicious unauthorized user.  But it's so easy to forget about testing the login screen!  This is because as a tester, you are in the application every single day.  Getting past the login screen is a step you take dozens of times a day to get to whatever feature you are currently testing.

Let's take some time to look at the various ways we should be testing login screens.

First, make sure that the password field masks text as you type in it.  Next, check to make sure that both the username and the password fields are expecting case-sensitive text.  In other words, if your username is "FOO" and your password is "bar", you should not be able to log in with "Foo" and "Bar".

Next, find out what the validation requirements are for the username and password fields.  How short can the values be?  What's the longest they can be?  What characters will be accepted?  Verify that the length requirements are respected in both fields, then test with every non-accepted character that you can think of.  Be sure to test with non-UTF-8 characters and emojis as well.  You may have heard a story several years back of a bank customer who broke the application by setting her password to have an emoji in it!

Also be sure to test for SQL injection.  For example, if you enter 1' or '1' = '1 into the password field, you may be telling the database to return 'true' and allow logging in, because of course '1' always equals '1'.

Now let's test with every possible combination of username and password states.  Each field can be either empty, incorrect, correct but with the wrong case, and correct.  This generates sixteen possible combinations:


It may seem like overkill to test all these combinations, but I have seen situations (fortunately that were only in the earliest stages of development) where I could log in with an empty username and password, or log in where both the username and password were incorrect!

Another helpful thing to test is putting an empty character or two at the beginning or end of the fields.  When the user submits their login request, empty characters should be stripped from these values.  If this does not happen, the user may wind up with a situation where they have typed their correct password: "bar ", and the password is not accepted because of the space at the end.  This is very frustrating for an end user who doesn't know the empty character is there.

Next, let's think about the kind of error message you are getting when you try to login with invalid credentials.  You don't want to give a malicious user any kind of hints about whether they have guessed a username or a password correctly.  If the malicious user types in "FOO" for the username and "password" for the password, you don't want to return a message that says "Invalid password", because this will let the malicious user know that the username is correct!  Now all they have to do is keep the username the same and start guessing at the password.  It is much better to return a message like "Invalid credentials".

Now let's take a look at what is passed into the server when you are making a login request.  Open up the developer tools for the browser you are using, and watch the request that goes through.  Do you see the username or the password in clear text anywhere?  If you do, this should be fixed!  Usernames and passwords should both be encrypted in the request.  You can also check the request by using an interception tool like Fiddler or Burp Suite.

Once you have logged in with correct credentials, take a look at the cookie or session id that has been set for your user.  Do you see the username and password anywhere?  All cookies, web tokens, and session ids should not include the user credentials, even if they are encrypted.

Finally, be sure to test logging out!  When you log out, the username and password fields on the login screen should be cleared, unless there is a feature to remember the credentials.  If there is such a feature, the password should definitely be masked and should give no indication of how many characters are in it.  Upon logging out, any session ids or web tokens should be deleted.  If there is no feature to remember credentials, the cookie should be deleted as well.  There should be nothing that you can grab from developer tools or interception tools to use to pretend that you are logged in.

This is a lot to test; fortunately, we can take advantage of automation for regression testing once we have done an initial test pass.  Here are a few ideas for what to automate:

API login calls using all the combinations of username and password listed above
UI logins with too many characters and invalid characters in the username and password fields; verify that the error message returned is the correct one
Visual testing of the login screen to verify that the password is not displayed in clear text (a good tool for visual testing can be found at https://www.applitools.com)

Security is such an important part of any application!  By running through all of these login scenarios, you can help bring peace of mind to your product team and to your end users. 



No comments:

Post a Comment