The phrase “Bank Grade Security” usually provides little comfort for those of us in the information security world, but nevertheless, buzzword-driven marketers still love to affix it to their content.

There’s been plenty written previously about the crypto configuration of online banking sites by analysing the configuration they use for SSL/TLS encryption. In this post, I’m not going to dwell on this, instead I’m going to talk about the security they use when storing our personal information.

That said, I’ve noticed that for a wide range of UK banking sites (including Virgin Money), HTTP Strict Transport Security remains unavailable - indeed Monzo are the only exception I noticed to this. This means the browser has no way of persistently knowing that it should connect over HTTPS, making Man-in-the-Middle attacks substantially easier. Further, they are also missing HTTP headers for things like XSS protection (e.g. via X-XSS-Protection).

Usually I’ve tended to quietly ignore banks poor security practices but I recently went through the process of registering for online banking for a Virgin Atlantic credit card (offered by Virgin Money) - whilst the airline is outstanding and I’ve had a great experience with Virgin Money’s service so far; in the sign-up process I’ve found their information security practices have been quite mixed. I’m writing this blog post so people can understand why it’s generally not a good idea to replicate these practices. Comparatively, I’ve experienced other banks using equally bad, or worse practices; instead I worry about what is considered secure for users in the banking industry.

Note that these are simply smells of bad practices I was able to detect from going through their user flow, I didn’t take any action to attempt to breach their systems.

Poor Identity Verification

The first dubious thing I noticed during the identity validation stage of the registration was the fact that they sought to verify my identity using phone numbers. Other than the fact they were verifying my identity on the basis of pieces of information that were relatively easy to get hold of; the way they implemented this was hysterical.

The first field shows me the first 5 numbers of my phone number and asks me to enter in the last 6 numbers. The second field asks me to enter in my contact phone number, this field came pre-filled on page load. In my case, my mobile number was identical to my contact phone number (like many, I don’t have a landline, so they only had one number on file). In essence they were asking me to verify a piece of information they had provided me on the very same page (whilst making it very clear that both the fields were identical):

Down the Password Security Rabbit Hole

Another suspicious sign was when setting or updating the password, there are some interesting requirements such as a limit of 8 to 20 characters for password length.

There is really no technical reasons to apply such restrictive length restrictions on the password; when there are such restrictions, it’s a sign the password is being stored insecurely in plain-text. Ordinarily when a password is stored, it should go through a Password Derrivation Function like PBKDF2, BCrypt or Argon2. A random salt is generated, and the password and salt are repeatedly put through a cryptographic hash function (with the hash re-injected each time) until the desired computational difficulty is reached. This means it is relatively trivial to validate if a password is correct, but effectively very, very hard to decrypt the password into raw form. Should the database be compromised, users who reuse the password on other sites have a degree of security.

Due to their password restrictions; users are incentivised to reuse passwords across multiple sites, remembering one password which meets ridiculous password requirements instead of generating unique passwords for each site. Similarly, long, unique passwords generated by password managers don’t fit in the required length requirements of the field. Virgin Money are certainly not the worst at doing this, on Twitter you’ll find examples of banks limiting passwords lengths to 8 characters - or in some cases just 6 numbers.

Their password requirements, allow you to set a password of Password1 (breached 108,522 in the Pwned Passwords database), but a randomly generated password from my password manager like xc2qmz9p#EFsaI2lNkmgXO57# is not acceptable, neither is something more memorable and more secure as GreatOrangeOpenSkyDijon (don’t actually use any of these examples now).

XKCD 936

Out of the Frying Pan, into the Fire

This is where things go from the frying pan to the fire. On login, I noticed something pretty horrific; they were asking me for different letters of my password instead of the whole thing.

Unfortunately this effectively much guarantees they aren’t storing my password in a secure way, they need to keep the password in plain-text to validate individual characters of the password. On another note; you can see from the screenshot below, you can even see how this approach is throwing my password manager off.

This ancient approach is designed to prevent things like keylogging, meaning that if a user’s password is captured - an attacker has a reduced chance of using it to login. Unfortunately, given password reuse and how common a significant percentage of password are; it does mean a significant percentage can be breached easily using credential stuffing lists or common password lists. Credential stuffing is a serious risk; when databases of breached sites are found, the usernames and passwords are injected into other sites until a breached account is found. Whilst they do also require a passcode, these are similarly liable to credential stuffing attacks.

Virgin Money did however partially redeem themselves, before viewing a credit card PIN number, they did send me an SMS verification number to provide some out of band verification that I was indeed the one requesting that action.

Unfortunately there are a number of problems with the way this has been implemented. Ordinarily, two factor authentication should be taken on any login action, to ensure the password isn’t the only thing they are validating you on; whereas the only action Virgin Money took this action on was viewing my PIN number.

Even after logging in over a VPN in a different country on a browser I’d never used to log-in to the service - they did not prompt me for an SMS login code. The same was true for repeated failed logins. They seemed to think a password and passcode was sufficient in these circumstances and never failed back to the SMS validation for login (even though this was already implemented for viewing PINs).

Furthermore, Two Factor Authentication over SMS is widely deemed to be insecure, with the US National Institute of Standards and Technology advising against it - they offered no opt-in offering to allow users to use a more secure and standardised approach to One Time Passwords such as Google Authenticator or hardware devices. That said, SMS Two Factor Authentication is certainly better than no Two Factor Authentication - so at least that’s something.

Virgin Money aren’t the only ones to poorly implement Two Factor Authentication; for example, I recently noticed that despite using Two Factor Authentication using both a hardware device and a mobile app to login to Barclays for a number of years (known as “PINsentry” by them), they continued to allow me to login using simply a passcode and memorable word (again, by asking me to enter in individual characters from such a memorable word). Despite introducing strong practices to enforce identity verification, they had let themselves down with a backdoor.

Concluding Remarks

Virgin Money’s practices aren’t great; but they’re not the worst I’ve seen for the banking sector. This does however raise an interesting question for us; what level of security should we acceot from our banks and those we trust with our sensitive information?