How risky is it to use email for custom sign in? - security

For a web application, where we need to store and manage users (SSO or openauth or what not is off the table), where we manage important business data, how risky is it to use an email address + password as the sign in?
For the last 15 years or so, encryption and protection techniques have improved, but we continue to use a proprietary user id, akin to using your bank card number for online banking; an id that will not be reused elsewhere. Customers and product owners are pushing to use email address because it is easier to remember.
I am concerned that there are a lot of websites that collect email + password pairs in order to use them to try to hack other sites; presumably asking you to sign up for an account for some humble service or other. What is this activity called?
I'm looking for some article or argument why using email+password for a site with sensitive business/financial information would be dangerous; or why it is not so bad. Again, I realize that provisioning our own accounts is not the ideal thing and am not looking for solutions at outsourcing authentication.

The "risk" of using a single authentication method for signing onto your application is difficult to determine without a risk assessment, and clearly defined system boundaries.
NIST 800-61 and NIST 800-63 gives guidelines on authentication methods for different levels of sensitive systems (in your case, a application). It will give you ideas on how to present your argument, and maybe an alternative solution, i.e., multi-factor authentication if the customer wants to authenticate using an e-mail address. This would mitigate the risk associated with malicious websites which collected e-mail addresses and passwords.
Keep in mind, password policy can also be managed to mitigate the risk behind a single authentication method using an e-mail and a compromised password associated with that e-mail.
All in all, it's not the ID that is important, but the authentication method and policies in place to mitigate the risks.

Using email + password as credentials is the widely accepted method of allowing users to log into sites on the web.
The advantage of using email is that everyone remembers their email address, whereas people will have difficulty in remembering which username or user ID they first signed up with if this is not their email address.
Username should not be considered private. This is the job of the password. Encourage your users to use a password manager such as LastPass where it can generate a 20 character completely random password (128 bits - uncrackable) which is different per site. LastPass will remember the username if this is not their email, so that solves this problem, however not using email can bring other problems such as username enumeration. If any signup function asks for a user to specify their username and you say that it is already in use, an attacker can use this to narrow the list of users in order to prepare for a password guessing attack. If you ask for email as step one of password reminder or signup forms, the system can send an email with a password reset link if already registered, or send an email with a link to the next step in the registration process if not.
In the end it all comes down to the value of the data your application is protecting. Adding two factor authentication is always a good step and can protect against password guessing and password reuse.
SSO or openauth or what not is off the table
Why is the case? Can't you use OAuth with claims based authorisation? You can still secure your application and make sure only the correct business users have access - it would just be that another entity is managing access for you.
I am concerned that there are a lot of websites that collect email + password pairs in order to use them to try to hack other sites; presumably asking you to sign up for an account for some humble service or other. What is this activity called?
Credential harvesting?

Related

Implementing password recovery if users have no email account

Ok, so I've inherited an open-source project with user logins that are a simple username/password combo. Unfortunately, if someone forgets their password, we don't have a password recovery option. I'm hoping to fix that now, but not sure how to do it securely, given that we don't have any other identifying characteristics. User accounts have no recovery email, no "secret questions," etc.
A user account consists only of 1) username, 2) encrypted password, 3) List of document ids which the user has editor access (but this is publicly visible by viewing the user's public page)
Now that I have access to the project, I will be implementing OAuth or similar, but as for old accounts with forgotten passwords that have since been logged out, is there any right way to ID my users so they can do a password reset?
There is no great way of doing this. You just don't have the information; not even enough to contact users. Until a user has supplied their username and password, you can't communicate with them.
You'll need to add a check that runs every time a user authenticates, which checks if they've set recovery data (email or whatever you decide on). From there you have a variety of options, depending on how important you find the recovery data. In order of severity, you could:
Disallow use of the site until they have added and verified
recovery data. Essentially, full authentication fails if recovery
data is not set.
Prompt them to add recovery data, but allow them to skip it.
Notify them that the ability to set recovery data has been added, but take no further action.
If you are dramatically changing login, you'll need to support the legacy method as well until such time as you want to abandon users who haven't made the switch.

How can I detect if a user already singed with a social account on my website and now wants to create a normal account?

How can I detect if a user already singed with a social account on my website and now wants to create a normal account?
How do I detect the changes?
My personal vision on this:
Let the user sign in with social auth then add the email in the database(mongo) but with no password?
Also when the same user wants to register on the website with the same email but without the social auth and a password, i should redirect him to his profile info from the social auth like username?
An example of what I am talking about:
User signs with google+ on stackoverflow
Then after a while comes back to sign for an account with the same email but a different password.
What is the best way to deal with this situation also from the GDPR standpoint can I use passport for this?
Thank you
When a user registers with social auth, you can also prompt for password (if you wish so) or create an account without it. Next time when a user registers using the same password, you should show an error message 'Email is taken'. In that case, user should receive an automated email that there was an attempt to use his email containing information on how this account was created (e.g. with Google+) - as a reminder.
Using social accounts for auth isn't safe and asking for password (requesting long passwords with special characters, upper/lower case letters) adds a little bit to the overall security. And Two-Factor Authentication takes it to the next level. For most websites, it should be secure enough. Temporarily blocking accounts after a number of unsuccessful attempts is easy to implement and protects from brute forcing.
Alternatively, a user should have an option to restore access to his account by means of requesting a password recovery URL to be sent to the email attached to the account. Then a user is prompted to input password that will be saved for the given account. Thus a user can log in to his account using email/password or the social auth that was used to create it.
With regards to GDRP, a user should be able to:
see what social accounts are connected to the profile and be able to detach them
delete his account (the right to be forgotten)
see what data is stored on him and export it (data portability)
modify data (Right to rectification)
opt-out/in for getting promo emails
manage advertising Cookies
There should be clear T&C provided with a full description of what data is stored, why and for how long.
Additionally, security (2FA, https, etc.)
This is in a nutshell ...

Company-wide password scheme for different customers

Consider a company that delivers a network of computers as part of its deliveries. And it does this for hundreds of different customers. All of the PCs need to have secure passwords. This at least means:
The password should conform to the basic password rules (capitalization, numbers, special characters, etc.)
The same password shouldn't be used for different customers.
The password shouldn't be easily guessable.
If possible, the same password shouldn't be used for different PCs in the network (but it may be acceptable to do so).
Since there is also a need to maintain these systems as part of the delivery, the operators need to be able to retrieve a password for a specific system easily without causing any security problems (like forwarding passwords in emails, etc.).
Here are my questions regarding such a setup:
Is it advisable to create a password scheme such that the operators can "calculate" the password without having to look up? [Problem is, once the scheme is disclosed, all systems will have a security problem.]
How should the passwords be stored/retrieved for good security? [Is there a program that can be used to access a secure database with a web interface?]
I found WebKeePass during my investigation (which looks promising). One other option was to print the passwords and keep them in a locked filing cabinet in a disused lavatory in a basement with a sign on the door saying 'Beware of the Leopard'? but I believe that wouldn't be convenient for the operator. I wonder what are the other options would be...
Update: The "web" interface doesn't have to be open to public access (i.e., it can be accessible only within a VPN).
Since the users aren't able to choose their password, the passwords should be generated randomly. If the passwords are generated using some algorithm, as you stated, once the algorithm is cracked, all of the passwords can be cracked.
If you must store retrievable passwords, you should still encrypt and salt them. See adobe's recent issue where 150 million of adobe's encrypted passwords were leaked. The problem with unsalted passwords is that even if I can't crack the encryption, I can still see everybody who has the same password as me.
Admin Retrieval
For admin-only retrieval of passwords, you could use a password vault system, where one password entered by a staff member unlocks access to additional stored passwords. Ideally, you should have a system where you can select and display a single password on the screen. It should encrypt the passwords, log accesses, and be controlled by an administrator.
This could be a web-based system, but hosted internally on an intranet, perhaps accessed through a VPN. RDP or something similar may also be viable, perhaps even using two-factor authentication.
Unfortunately, we don't recommend products on StackOverflow.
End User Retrieval
We've designed a system in the past where you can recover a password via a HTTPS secured web site. You simply enter your username, and a random one-time-use retrieval code is delivered to the email address on record.
While we're not in control of the security level on their email account, we at least assume that only the user knows the password to access the email account. This forces the user to re-authenticate in some form in order to retrieve their password.
They then type the retrieval code into a web form and are shown their password. Again, this web site is secured with HTTPS. Additionally, the user must keep the web page open during the transaction (secure session), and the IP address must not change during the transaction.

How do I validate that my the openid.op_endpoint when a request is completed

I have an Open ID based authentication system on my site.
Occasionally users will have an account registered under foo#gmail.com and they will attempt to login using the google open id provider https://www.google.com/accounts/o8/id, in this case I would like to automatically associate the account and log them in.
When the process is done I get a payload from somewhere claiming that openid.op_endpoint=https://www.google.com/accounts/o8/id.
My question:
Can I trust openid.op_endpoint to be correct? Can this be spoofed somehow by a malicious openid provider?
For illustration, lets say someone types in http://evil.org as their openid provider, can I somehow end up getting a request back that claims openid.op_endpoint is google? Do I need to store extra information against the nonce to validate?
The spec is kind of tricky to understand
Yes and no. No you shouldn't trust anything you get over the wire, including openid.op_endpoint. But if you are using a secure OpenID library, this parameter is verified before the user is ever allowed to log into your site. The OpenID spec does, in fact must, provide a way for this and other parameters to be verified and without verification the authentication protocol is worse than useless.
So, make sure your library is decent. Then yes, trust the openid.op_endpoint parameter. But not the one you get from the query string yourself, since OpenID messages can be POSTed to you, and the parameter would not show up in the query string. Worse, if you were to check the query string in this case, you'd probably be opening yourself up to a security hole where an attacker could add that parameter to the querystring and fool you while complying with the library's requirements. So it's best to use the API the library exposes to find out what the OP endpoint is.
As far as linking the accounts in this way, this is a good approach since Google will only send email addresses it knows are truly controlled by the user. If you've already required your user to go through an email verification step, then linking the account is safe. But if the email address you have for the user wasn't ever verified, then you must not link the accounts based on this match or I can hijack someone else's account by creating an account that has someone else's email address, and then wait for them to log in using OpenID and now I can get into their account.

How do you support a web app with hashed or encrypted passwords?

When supporting a new web app in an enterprise environment, it is often necessary to log in as a specific user in order to diagnose a real or perceived problem they are having. Two opposing issues apply here:
Best practice is to use hashed or encrypted passwords, not clear text. Sometimes, there is a third-party SSO (single sign-on) in the middle. There is no way to retrieve the user's password. Unless the user provides it (not encouraged), there is no way to log in as that user.
Many web app's have personalization and complex authorization. Different users have different roles (admin, manager, user) with different permissions. Sometimes users can only see their data -- their customers or tasks. Some users have read-only access, while others can edit. So, each user's view of the web app is unique.
Assume that in an enterprise environment, it isn't feasible to go to the user's desk, or to connect directly to their machine.
How do you handle this situation?
Edit: I want to reiterate that in a large financial institution or typical Fortune 500 company with hundreds of thousands of employees all of the country, and around the world, it is not possible for a mere developer in some IT unit to be able to directly access a user's machine. Some of those are public-facing web apps used by customers (such as online banking and stock trading). And, many of those are intranet applications rely on Active Directory or an SSO, meaning that user credentials are the same for many applications. I do thank you all for your suggestions; some may be highly useful in other kinds of environments.
A number of these ideas inconvenience the user, either by forcing them to change their password, or by occupying their desktop for your debugging session.
Markc's idea is the best: augment your authentication logic to allow superusers to log in as a particular user by supplying not the user's credentials, but the user's name plus their superuser credentials.
I've done it like this in the past (pseudo-ish python):
if is_user_authenticated(username, userpassword):
login the user
else if ':' in userpassword:
supername, superpassword = userpassword.split(':')
if is_superuser_authenticated(supername, superpassword):
login the user
In other words, if the username and password don't authenticate, if the password has a colon, then it's actually the admin username and admin password joined by a colon, so login as the username if they are the right admin username and password.
This means you can login as the user without knowing their secrets, and without inconveniencing them.
For our web applications we use a process that for lack of a better term is defined as 'hijacking' a user's account.
Basically, administrators can 'hijack' a user's account with a simple button click. In the code, you simply use a unique identifier (user id works in a less secure environment) that then establishes the necessary credentials in the session so that they can then work within that user's profile. For a more secure environment you could use a unique hash for each user.
In order to ensure that this hijack method is secure, it always first verifies that the request is being made by an authenticated administrator with the appropriate rights. Because of this it becomes necessary for either the administrator's session to be hijacked or for their authentication credentials to be captured in order for someone to ever exploit the hijack function within the application.
I had 4 ideas. While I was typing 3 of them were already suggested (so I upvoted them)
Variant on idea 3 - impersonation:
To make this as "identical as possible" to a normal login with minimal code changes, you might add the ability to impersonate directly at login by supplying Admin credentials plus an alternate username, e.g. login as Admin:user, adminpassword. The system would treat this exactly as logging in as user with userpassword.
Idea 4: Can you access the password store? If so, temporarily replace the user's hash with the hash of a known password. (the passwords are often stored online in a database. A SQL Query tool can do the swaps )
An administrator should be able to change a user's password. Change the password for the user to something you know. You can then log in as that user.
Tell the user to reset his/her password after you are done debugging.
Usually by some sort of remote control software that can be used to view their desktop. If they're on a Windows terminal server, then the built in admin tools can be used for that. Otherwise I'd use something like VNC across an internal network, or an external service like LogMeIn (http://www.logmein.com/).
Could you have a testing environment where there is a regular cut of live data copied to (obviously sanitised to meet any security or data protection issues). A user similar in setup to the one having trouble could be used to troubleshoot or indeed the very user if this is allowed.
Use a remote desktop client as mentioned in other answers, but again this may not be practical for you. If you have these rights within the domain, I have heard of error handling even doing a screenscrape and including this in logs! but this sounds a little odd to me.
Could you have an admin tool to clone a user into a demo account?
The solution we have used in our web apps is to have the authN/authZ return the desired user as the effective user. We do this by having an admin feature to setup a masquerade, and then when we ask for the currently logged in user (current_user), we handle the masquerade:
def current_user_with_effective_user
if masked?
current_user_without_effective_user.masquerade_as
else
current_user_without_effective_user
end
end
alias_method_chain, :current_user, :effective_user

Resources