There is an internet banking website that I use a lot and its way of authenticating users is to ask about their security question and only enter 3 random characters of their password.
I have always wondered how they store users' passwords on their system, surely it is not plain text? or is it? Also it cannot be hashed because the characters that are required for logging in changes each time. What is the idea behind it?
These kind of authentication systems are intended to provide protection against keyloggers/traffic interception, on the basis that if the login details are intercepted, the attacker only gets a few characters of the password rather than the whole thing. Sadly large parts of the banking industry still use them rather than just implementing actual MFA (although that seems to be slowly improving).
You're correct that it's not possible to use this kind of authentication if the password is hashed, however that doesn't necessarily mean that it has to be stored in plain text.
Assuming that they've implemented it well, the password should be stored encrypted, rather than in plain text. There might also be an element of separation, so that the system storing the passwords is separate from the frontend that the user is interacting with, so you could have an authentication flow like this:
The frontend makes a query to the authentication microservice with the username/ID.
The microservice responds with which three characters it wants.
The user is asked to input the characters.
The frontend sends these three characters to the microservice.
The microservice responds with a success or failure.
This way, a compromise of the frontend doesn't directly expose the users' password, and you can implement controls (such as logging and rate limiting) on the authentication microservice to help identify and protect from a compromised frontend.
Related
When registering for an account or when resetting a password of a web service, users are often required to type their password twice to ensure that they do not accidentally misspell their passwords.
If accidental misspelling is the only consideration for this feature, it would be acceptable (perhaps even better, from a website design perspective) for the retyped password to be validated by browser/client JavaScript rather than being sent to the server for validation.
Am I right that accidental misspelling is the only consideration for this feature?
This is a bit pedantic, but a confirmation field is for accidental mis-entry rather than misspelling as such given the nature of passwords.
To answer your question; yes, a password re-entry field is just for verification of the user's input.
JavaScript could be used to ensure the entry meets the password requirements (length, special/valid characters, strength, etc.), but what if the user has JavaScript disabled? You'd have to code for the password to be validated server side in this case. Also, it's possible that, as the code is client side, it could be tampered with to bypass your checks (some people just like to break things). On top of that, from a web design perspective, the client will need to download more code in order to achieve this instead of posting an extra form field so there's an extra (albeit very small) data-use overhead when considering mobile.
All this can be rendered unnecessary however. If your password reset process is secure and robust enough (e.g. require email address verification), then you arguably don't need the user to verify that they've typed in what they meant to. You'd need a process to remove accounts that hadn't been validated though, in case they mis-entered their email address... unless you get them to enter their email address twice ;) For example, based on the fact Stack Overflow only required me to enter a password once upon registration, this seems to be the approach this site uses.
Hope this helps.
I am building a simple iPhone game which has a community maps feature.
Users sign up for an account with just their email and password, and then they can build, upload and download custom maps.
Now I know that sending the username and password with every request is usually a bad idea, but it is a lot easier for development instead of having to deal with login session, and I think it is okay for situations where security isn't a major concern.
The most important thing is to protect the user's password as they likely use the same password for multiple accounts.
So the simple approach I think is this: Send the user's username and password as one md5 hash with every request. Would this be okay?
Sure there is a risk someone might hijack the request, but login sessions have the same risk. And if a hacker got hold of a user's login session, don't they just need to force that user to log off so the client will send the user's username and password in the next request?
I haven't got any experience with mobile app development, however some general principles still apply. Firstly MD5 is flawed, don't use it. And if you are going to use a different algo (depends on your choice, and what what security/speed you are looking for, for thing like that I'd probably go for blowfish, but SHA512 should also do the job), definitely use salts.
I still think though that a simple session management would be better than sending the login information with every request, simple random session id should do (you generate it upon log in and associate with a particular user); of course there you run in a trouble with randomness of the ids (if they are predictable it is obviously a problem).
But I suppose the major point here is how will the app communicate with the server; if it is encrypted (HTTPS I would presume) you should be fine either way, I think is more important than whether you use sessions or hashed login info. And usage of HTTPS should take care of your worries about request/session hijacking as well (unless someone cracks the encryption with 200 modified PS3 units :) )
I have a simple site with a sign-up form. Currently the user can complement their registration with (non-critical, "low security") information not available at the time of the sign-up, through a personal (secret) URL.
I.e., once they click submit, they get a message like:
Thanks for signing up. You can complement your registration by adding information through this personal URL:
http://www.example.com/extra_info/cwm8iue2gi
Now, my client asks me to extend the application to allow users to change their registration completely, including more sensitive information such as billing address etc.
My question: Are there any security issues with having a secret URL instead of a full username / password system?
The only concern I can come up with is that URLs are stored in the browser history. This doesn't worry me much though. Am I missing something?
It's not the end of the world if someone changes some other users registration info. (It would just involve some extra manual labor.) I will not go through the extent of setting up https for this application.
This approach is not appropriate for sensitive information because it's part of the HTTP request URL, which is not encrypted and shows up in many places such as proxy and other server logs. Even using HTTPS, you can't encrypt this part of the payload, so it's not an appropriate way to pass the token.
BTW, another problem with this scheme is if you send the URL to the user via email. That opens up several more avenues for attack.
A better scheme would require some small secret that is not in the email. But it can be challenging to decide what that secret should be. Usually the answer is: password.
Another potential problem lies with the users themselves. Most folks realize that a password is something they should try to protect. However, how many users are likely to recognize that they ought to be making some sort of effort to protect your secret URL?
The problem here is that although it is hard to guess the URL for any specific user, given enough users it becomes relatively easy to guess a correct url for SOME user.
This would be a classic example of a birthday attack.
ETA: Missed the part about the size of the secret, so this doesn't really apply in your case, but will leave the answer here since it might apply in the more general case.
can complement their registration with (non-critical, "low security") information
It's hard to imagine what user-supplied information really is "low-security"; even if you are asking for a password and a username from your customers you are potenitally violating a duty of care to your customers; a large propertion of users will use the same username/password on multiple sites. Any information about your users and potentially a lot of information about transactions can be used by a third party to compromise the identity of that user.
Any information about the user should be supplied in an enctypted format (e.g. via https). And you should take appropriate measures to protect the data you store (e.g. hashing passwords).
Your idea of using a secret URL, means that only you, the user, anyone on the same network as the user, in the vicinity of a user on wifi, connected to any network between you and the user, or whom has access to the users hardware will know the URL. Of course that's not considering the possibility of someone trying a brute force attack against the URLs.
C.
The secret URL means nothing if you're not using SSL. If you're still having the end-user transmit their identifying information across the Internet in the clear, then it doesn't matter how you're letting them in: They are still exposed.
The "secret URL" is often referred to as security by obscurity. The issue is that it is super simple to write a script that will attempt various combinations of letters, symbols, and numbers to brute force hack this scheme.
So if any sensitive information is stored you should definitely use at least a username and password to secure it.
Most of the online sites on registration do send a link to activate the site and on any further correspondence with the end user they provide information about the site and also provide the login credentials with password in clear text (as given below)
Username - myname#gmail.com
Password - mysecretpassword
What would you do in such a case? From a usability perspective does it make sense to send the password information in clear text or should you just avoid sending this information. I was under the impression that most of the passwords are MD5 hashed before storing in the database and hence the service provider will not have any access to clear text passwords, is this a security violation?
It's a commonly-held fallacy that if you receive a password in plain-text it means they aren't stored securely - passwords like any other data can be stored using reversible encryption.
Having said that, it's pretty likely anyone that sends you a plaintext password does not have a clue about security and is probably storing them carelessly (unless the passwords are used as weak real-world identifiers, say as part of an in-store membership scheme, in which case they shouldn't be called passwords lest your customers get confused).
If you send a password plain-text you may as well assume that if it is linked to something important then it has been compromised. There are just too many weak points. You can also do a lot more unintentional damage.
The email could be intercepted giving someone else the password.
Someone could see them open the email on their screen (been at mates houses and had this happen to both of us so many times, and every time is a massive headache to go change all your passwords).
The email might be forwarded to other addresses which are not secure.
The email might bounce/encounter a server error and then you (perhaps your untrusted staff or outsourced helpdesk too?), and the email server's system admin will probably get copies of the original email.
Someone who obtains access to the user's emails through a cookie hijack or even just a briefly unattended open email account will now be able to see their password. Worse, their password is probably used elsewhere (or at least has a common stem, e.g. "password1", "password1$$" "passwordSuperSecure123") so you've now compromised more than just your own service. Worse still, it might be the password to the email account that's been hijacked and now they can steal this person's email account and thus identity for a much longer time than the expiry date on the cookie/session. (This has all happened to people I know).
Yes, this is definitely a security violation. Only a salted and hashed version of passwords should be stored.
It is common to have reset password functionality that sends either a temporary auto-generated password (which should be good for only one login) or a one-time reset link. This does mean your other accounts are only as secure as your email.
However, you should steer clear of any site that will email your actual password in clear text.
There are always trade-offs, and developers have to consider useability, the savvy-ness of the intended users, the secrecy and importance of the data, the frequency that the website will be used, and so on. Of course users don't want their privacy violated, but on the other hand "ordinary" web users may be turned off by having to remember a password, or even having to invent one in the first place (some websites simplify user registration by generating a random password and emailing it). Website developers have a responsibility to keep the users' best interests in mind when designing security.
My advice is that passwords should only be emailed in the clear when they are randomly generated. This avoids the following awkward scenario: a user registers with a password which they are already using for various other web services, and then receives a registration confirmation email containing the password they just entered. A lot of users may not be security-conscious enough to use unique passwords for every website, but they are security-conscious enough to recognize that "sensitive" passwords should not be sent around by email.
As much as I understand it is a good idea to keep passwords secret from the site administrator himself because he could try to take a user's email and log into his mailbox using the same password (since many users use the same password everywhere).
Beyond that I do not see the point. I know it makes more difficult the dictionary attack but... if someone unauthorized got into the database, isn't it too late to worry about passwords? The guy has now access to all tables in the database and in a position to take all the data and do whatever he wants.
Or am I missing something?
The bigger problem is that people tend to use the same password everywhere. So if you obtain a database of usernames and unsalted passwords, chances are good they might work elsewhere, like hotmail, gmail etc.
The guy might be in a position to do everything he/she wants to your system, but you shouldn't allow him/her to do anything with other systems (by using your users' passwords).
Password is a property of your users. You should keep it safely.
Many of your users use the same credentials (usernames/passwords) at your site as they do at their bank. If someone can get the credentials table, they can get instant access to a bunch of bank accounts. Fail.
If you don't actually store passwords, then attackers can't steal your users' bank accounts just by grabbing the credentials table.
It relies on the fact that a hash is a one way function. In other words, its very easy to convert a password into a hash, but very difficult to do the opposite.
So when a user registers you convert their chosen password into a hash and store it. At a later point they login using their password and you convert the password to its hash and compares it this is because, to a high level of probablity if (passwordhashA == passwordhashB) then passwordA=passwordB.
Salting is a solution to a related problem. If you know that someones passwordhash is, say ABCDEF, then you can try calcuolating hashes for all possible passwords. Sooner or later you may find that hash('dog') = ABCDEF, so you know their password. This takes a very long time, but the process can be speeded up by using pre-created 'dictionaries' where, for a given hash you can look up the corresponding password. Salting, however means that the text that is hashed isnt a simple english word, or a simple combinationofwords. For example, the case I gave above, the text that would be hashed is not 'dog', but is 'somecrazymadeuptextdog'. This means that any readily available dictionary is useless, since the likelyhood of it containing the hash for that text is a lot less than the likelihood of it containing the hash for 'dog' This likelihood becomes even lower if the salt is a random alphanumeric string.
The site admin may not be the only person who gets access to your password. There is always the possibility of a dump of the whole database ending up on a public share by accident. In that case, everybody in the world who has internet access could download it and read the password which was so conveniently stored in cleartext.
Yes, this has happened. With credit card data, too.
Yes, it is highly probable that it will happen again.
"if someone unauthorized got into the database, isn't it too late to worry about passwords?"
You're assuming a poor database design in which the authorization data is comingled with application data.
The "Separation of Concerns" principle and the "Least Access" principle suggest that user credentials should be kept separate from everything else.
For example, keep your user credentials in an LDAP server.
Also, your question assumes that database credentials are the only credentials. Again, the least access principle suggests that you have application credentials which are separate from database credentials.
Your web application username and password is NOT the database username and password. Similarly for a desktop application. The application authentication may not necessarily be the database authentication.
Further, good security suggests that access to usernames and passwords be kept separate from application data. In a large organization with lots of database users, one admin should be "security officer" and handle authentication and authorization. No other users can modify authorization and the security officer is not authorized to access application data.
It's a quick audit to be sure that the security officer never accesses data. It's a little more complex, but another audit can be sure that the folks with data authorization are real people, not aliases for the security officer.
Hashed passwords is one part of a working security policy.
Of course, storing hashes of passwords instead of plain-text does not make your application secure. But it is one measure that increases the security. As you mentioned if your server is comprised this measure won't save you, but it limits the damage.
A chain is only as strong as its weakest link
Hashing passwords is only strengthening one link of the chain. So you will have to do more than that.
In addition to what has already been said regarding salting, there's another problem salting solves :
If you use the same salt everywhere (or no salt at all), it's possible to say just by looking at the database that user foo and user bar both have the same password (even if you don't know what the password is).
Then, if one achieve to get foo's password (using social engineering for example), bar's password is known as well.
Also, if the salt is everywhere the same, one can build up a dictionary dedicated to this specific salt, and then run a brute-force attack using this 'salted' dictionary.
This may be a bit off topic, but once in a while, I notice some websites are not using hashing (for example, when I click the forgot password button, they send me my password in cleartext instead of allowing me to chose another one).
I usually just unsubscribe, because I don't think I can trust a website designed by people not taking the elementary precaution of hashing passwords.
That's one more reason for salting:)
People seem far too complacent about this! The threat isn't some guy with shell access to your system or to the backup media, it could be any script kiddie who can see the unprotected (but dynamic) part of your site(*) and a single overlooked SQL injection threat. One query and suddenly he can log in as any user, or even as an admin. Hashing the passwords make it far less likely that the attacker can log in as any particular user using their password -or- update a record with their own password.
(*) "unprotected" includes any part of the site that can be accessed as a self-registered user. Contrast this to a bank site, for instance, where you must have an existing bank account to gain access to much of the site. An attacker could still open a bank account to gain access to the site, but it would be far easier to send big guys with bigger guns after him when he tries to crack the system.