I've been given the task of finding and evaluating some authentication libraries for use in one of our products and one of the selling features being pushed by some solutions is "two-factor authentication".
What is this method and how does it work? Are there better methods (such as three-factor authentication, I guess)?
Two factor authentication is using two factors to authenticate a person (or sometimes a process).
This might be a PIN number (something you know) and a debit card (something you have).
There are many authentication factors that might be used:
Authentication factors apply for a
special procedure of authenticating a
person as an individual with
definitively granted access rights.
There are different factor types for
authentication:
Human factors are inherently bound to the individual, for example
biometrics ("Something you are").
Personal factors are otherwise mentally or physically allocated to
the individual as for example learned
code numbers. ("Something you know")
Technical factors are bound to physical means as for example a pass,
an ID card or a token. ("Something you
have")
From wikipedia.
Which factors you choose depend on the type of access required, security needed, cost, and especially what people are willing to put up with.
People get irritated with strong passwords that change every 4 months, so you might find employees happier with laptops that have fingerprint scanners and they can use a weak password and a fingerprint - two factor authentication may be easier for users.
But others might not like the privacy implications of biometric security and would rather carry around a keychain device that produces numbers which are typed in along with a password.
High security situations may require all three factors - something you have such as a card, something you are such as retinal imaging, and something you know such as a password.
But the costs and irritation go up as you add more levels.
-Adam
"Are there better methods (such as three-factor authentication, I guess)?"
The issue isn't simply more factors. It's a better mix of factors.
Passwords are easily lost and compromised. People write them on stickies and put them on the bottom of their keyboards.
Other non-password factors are part of the mix. For browser-based apps, you can use IP address, and other PC-specific material that floats in as part of the HTTP headers. For desktop apps (like VPN connections) independent key generators or plug-in USB readers might provide additional factors.
Its when two (or more) different factors are used in conjunction to authenticate someone.
For example, a bank might ask you for your account number and pin number. And sometimes, like when you call call centers, they might ask you for additional factors such as name, dob, phone number, address etc.
The theory is that the more factors you can authenticate against, the higher the probability that you are dealing with the correct person. How well it works and how much more secure it is is debatable in my opinion...
Factors include:
Human factors are inherently bound to the individual, for example
biometrics ("Something you are").
Personal factors are otherwise mentally or physically allocated to
the individual as for example learned
code numbers. ("Something you know")
Technical factors are bound to physical means as for example a pass,
an ID card or a token. ("Something
you have")
See: http://en.wikipedia.org/wiki/Two-factor_authentication
I'll take this from a completely different tact. All these answers are correct, of course, but I want to broaden the topic a bit - to think about where & when to apply two-factor authentication. There are three areas where strong authentication can be used: session authentication, mutual authentication and transaction authentication. Session auth is what most people think about when they think about 2FA. But imagine if people only had to use an OTP when making a banking transaction. The attack surface goes from "when logged in" to "When making a transaction", which is much smaller. if the transaction authentication uses a public key system to sign the tx, then all the better.
Mutual authentication is some system that attempts to thwart MiTM attacks. You can think of the little pictures some banking sites use, but they are totally ineffectual because there is no crypto involved. here's how we do mutual auth, by validating the site's ssl cert for the user: http://www.wikidsystems.com/learn-more/technology/mutual_authentication/. There are other ways to do the same thing, of course.
Related
ASP.Net Core has protection against brute force guessing of passwords, by locking the account after a fixed number of login attempts.
But is there some protection against credential stuffing, where the attacker tries a lot of logins, but always with different usernames? Locking the account would not help, since the account changes on every attempt.
But maybe there is a way to lock an IP against multiple login-attempts or some other good idea to prevent credential stuffing?
I'd recommend using velocity checks with redis, this is basically just throttling certain IPs. Also some fraudsters will also rotate IPs, you could also detect when logins are happening more frequently (say 10x the norm) and start to block all logins for that short window. I wrote a blog post detailing some of the above. The code is all in node, but I did give some high level examples of how we stop fraud at Precognitive (my current gig). I will continue to build upon the code over the next couple of months as I post more in my Account Takeover series.
https://medium.com/precognitive/a-naive-demo-on-how-to-stop-credential-stuffing-attacks-2c8b8111286a
IP throttling is a good first step, but unfortunately it won't block a large number of modern credential stuffing attacks. Tactics for savvy credential stuffers have evolved over the past few years to become more and more complex.
To be really effective at blocking credential stuffing, you need to be looking at more than IP. Attackers will rotate IP and User-Agent, and they'll also spoof the User-Agent value. An effective defense strategy identifies and blocks attacks based on real-time analysis of out-of-norm IP and User-Agent activity, plus additional components to enhance specificity (such as browser-based or mobile-app-based fingerprinting).
I wrote a blog post looking at two credential stuffing attacks in 2020, which I call Attack A (low-complexity) and Attack B (high-complexity).
Attack A, the low-complexity example, had the following characteristics:
~150,000 login attempts
1 distinct User-Agent (a widely used version of Chrome)
~1,500 distinct IP addresses (85% from the USA, where most of the app users reside)
Attack B, the high-complexity example, had the following characteristics:
~60,000 login attempts
~20,000 distinct User-Agents
~5,000 distinct IP addresses(>95% from USA, >99% from USA & Canada)
You can see that with Attack A, there were about 100 login attempts per IP address. IP rate-limiting may be effective here, depending on the limit.
However, with Attack B, there were only 12 login attempts per IP address. It would be really hard to argue that IP rate-limiting would be effective for this scenario.
Here's my post with more in-depth data: https://blog.castle.io/how-effective-is-castle-against-credential-stuffing/
Full disclosure: I work for Castle and we offer an API-based product to guard against credential stuffing.
It might sound like a silly question, because passwords of course need to be hashed and never store the original.
However, for API secrets, generally I see them displayed in the clear when signing up for them.
For example, if I go to the google api console and look at my credentials page, I can view my client secret, same for twitter.
Surely api keys are just as sensitive as passwords?
Is it just because from the provider side, you can be confident that a sufficiently strong password is being generated?
If that's the case, then that doesn't provide any protection is your database is compromised.
Or is it perhaps because if you are using token based authentication, you're either doing password grant type, which requires you to send your credentials along with the client id and secret, or a refresh token, so a user would have already had to have been compromised?
I can imagine a few possible answers to this:
In some cases, it may be required for the server to have persistent storage of the plaintext API key in order to satisfy usability requirements (Google and Twitter being examples).
In some cases, the API key alone is not enough to do much at all -- additionally one needs to have an authenticated account -- and therefore the API key by itself is of limited value (hence less value than a password).
In a number of cases, the API key is hardcoded in a client application (especially mobile applications, which almost always do this) and therefore it does not make sense to add the extra protection on the server side when the same token can be trivially extracted from the client.
The security industry is just not that mature yet. Maybe once hackers start dumping API keys, ideas like this may be taken more seriously.
BTW, I am very serious about the last point. The truth is that a lot of good ideas don't become a reality until there is a critical mass of support behind them. As an example, I once blogged about a related topic -- protecting user confidential information by hashing it in the database but in a way that it could be recovered when the legitimate user logs in. I used Ashley Madison as an example -- in that case, the hackers were more after email addresses, phone numbers, and physical addresses than passwords. So when the hackers snatched the database, they immediately had what they wanted, and they could care less about the bcrypt encoded passwords (in fact, some older passwords were encoded with only MD5!) Unfortunately, concepts like this do not have enough of a push to make them a reality. Even zero-knowledge web designs are very few in the real world.
I am doing a HIPAA application soon and it requires 2 factor authentication. Can anyone give me an example? I am thinking a secure login and then a form that requires the user to enter their birth date or something.
Thanks,
Darren
There are 3 general types of factors:
“Something you know” – memorized information (e.g., a password or answer to a
secret question).
“Something you have” – possession of a unique item containing secret
information (e.g., a smart card, bar code, or USB-interface device).
“Something you are” – a physical trait that can be converted to digital
information using specialized hardware (e.g., a retina or fingerprint scan or voice
recording analysis).
You need to pick from 2 of these 3 categories to have true 2-factor authentication.
Wikipedia has a great listing of various types of Two Factor Auth. Check it out here.
2-factor authentication usually requires something the user knows, like a password, and a token from something the user has, like a SecurID fob, or nowadays maybe a biometric identifier, like a fingerprint reader.
A password & birthday, while being two distinct things, are both knows items and wouldn't constitute a proper 2-factor identification.
See this article or search for information using "2 factor authentication", Google and Bing both show lots of references.
What you're describing (password + verification input) is still single factor authentication.
Two factor authentication also requires something the user has in their possession (smart card, dongle, etc.)
Three factor authentication (for completeness) is all of the above plus some sort of biometric input from the user (fingerprint, retinal scan, hand geometry)
2FA will be simple One time password as hardware or software (mobile , PC ) and
we have done few deployments of 2FA tokens for HIPAA compliance.
CryptoPhoto is a very easy to use "Strong Authentication" 2FA solution, with additional protection aginst Phising and other threats. You don't have to ship expensive hardware gadgetry to end users either - it's a fully self-contained solution.
This is not a technical question. How do small organizations keep sensitive information that must be shared among several individuals safe, such as root passwords to production servers? Not all people that need to have access work in the same location.. new passwords can be distributed by phone, but what rules should be enforced for team members in the storing of the passwords?
UPDATE: this question is not about the proper usage of root passwords -- that was just meant as an example. Maybe a better example would be the SSL passphrase or any other password that must be shared among people performing administrative tasks. The fact is, root passwords and the like need to be generated and stored and usually more than one person needs to have access, sometimes those people work in different locations. The question is about storage protocols. Thanks.
You shouldn't be handing out (or using) root passwords to any servers, production or otherwise. You shouldn't be sharing passwords.
People should log in as themselves (authentication) with their own user ids passwords; that's one half of the picture.
When properly logged in they should be given rights (the authorization side of the picture) as appropriate. You can use things like sudo for general OS purposes, and the rights mechanisms inside databases, etc.
These are two separate issues. Don't cross the streams!
I personally recommend to people facing similar problems to use something like keepass or roboform to store passwords. These programs encrypt your passwords on a thumbdrive using a master password that the individual remembers, so that they need only remember the master password. In the event that someone looses their thumbdrive, they will have a window of time in which they can report the compromised thumbdrive, and allow you to change passwords. It will take a little bit of time, depending on the master password's strength, before the person who stole the thumb drive would be able to brute force the master password to get at all the other stored passwords.
Additionally, avoid having any account shared by more than 3 people, if at all! Instead, consider creating each individual an account with equivalent access. If a malicious employee has access to an account which they know is shared, it might be more tempting for them to do malicious things since they know you could not hold them accountable, since it could have been any of several people sharing the account.
This also means you don't have to change the password every time someone quits. Instead, you just disable/delete their account. So although you have more accounts to manage, you have less overhead when someone leaves since you don't have to notify everyone of a changed password.
Edit: Oh Roboform also has a online password sync service over SSL. So you could just have people retrieve passwords via syncing. It's kinda cool once you get used to it.
With the advent of sudo we seldom need to use a root password any more. In my old shop, the root password was written on a card, sealed in an envelope, and locked in a drawer in the sysadmins' area. Those who needed to know had keys to the drawer.
Anybody opening the envelope was required to change the password and put the new password in a new sealed envelope. The envelope was not opened often.
This system is probably really bad professional practice, but in a small shop where everybody knew everybody, it worked well.
In a prototype & R&D lab where I formerly worked, there were 'standard' lab passwords for things like root, administrative access to consoles, switches, etc. These are simple, easy to remember, and shared verbally with anyone who needed them. In general, if you could physically get into the lab, you were authorized to have these passwords.
In the manufacturing facility, new systems were built and configured for customers. The customer got to choose all the passwords, and they were printed on a set of forms that were attached to the rack with the systems. Remote access was provided as required, and the passwords were sent in an e-mail, or given over the phone. It was fully expected that the customer would change these passwords as soon as the system was delivered to them.
For the IT & Production labs, almost no one had root access. Almost everyone did have sudo access with somewhere between no limits and only the ability to mount virtual filesystems...depending on the person and the system. It was very rare to get sudo access to launch a shell as root. This left a very clear log trail of all the commands you ran as root. That log was used to tar & feather more than one person over the years.
At a help desk / support role I had many years ago, each tool expert picked their own administrative passwords. These were recorded in an envelop that was locked in a safe in the machine room. If someone needed admin access, they could open the envelop, read the password, and note in the log that they knew the password and then re-seal the password in the envelop. It was up to the tool owner to decide if the password needed to be changed. This system was used for more than 5 years...and in one case actually helped the project to survive the "bus test" (heart attack) for one team member.
Different standards for different kinds of systems and labs. That is reasonable. I find that when passwords need to be shard, it is best if the password is simple, short, and communicated verbally (either in person or over the phone). I find that the only password that should never be shared is the one for my personal account. Any root/admin/tool specific passwords should be backed up in at least one other head...if not recorded in some manner.
you can use a program like anypasswordpro to share passwords. It is encrypted and has levels of access :)
Be realistic. Whether you like it or not, people in small teams are going to write passwords on sticky notes, IM them, or be tempted to email them, especially when they perceive no threat.
One measure I've found useful with small groups is to establish an obfuscation protocol.
For example, all passwords communicated or stored via voicemail, email, IM, or paper will have
1) the order of their characters reversed
2) a random character or word placed in between each password character
3) phonetically pronounced password characters.
For example:
Password: VMaccp#ss1
Obfuscated: one 2 es df es 23 at sd pee fd see dfs see fxz ay df EM sd VEE
The key is to establish some kind of encoding that is virtually impossible for someone to figure out without knowing the protocol, which is easy to remember.
Keep in mind this is for small groups without life-or-death security. Obviously for larger groups or those protecting extremely sensitive financial data stronger more cumbersome measures are appropriate.
Is there any best practice data model for authentication/ authorization schema?
A data model that consists of a mapping of roles to privileges is fairly flexible and suits most purposes.
Then you assign roles to users (the concept is essentially the same as that of groups)...a user may have more than one role, and their role(s) define the privileges they have.
In the code, you check (via their roles) that the user holds the required privilege to perform a function.
Authentication is separate, that's just validating who the user is, not what they can do. Usually you should maintain this separation (though there are schemes that are designed so that they only care what the user can do, not who they are).
In your design you can visualise the access control system as a matrix (roles to privileges).
I would also expand on the 'do not store passwords' answer - don't design your own authentication scheme at all. You'll probably get it wrong. Reuse one that is proven.
The single most important thing is
Do Not Store Passwords
Store digests of passwords. See RFC 2069 and this Wikipedia article. When someone tries to authenticate, you compare the digest of their input to the digest you have to see if their credentials match.
I'll add a caveat to S.Lott's answer of "Do Not Store Passwords: Store digests of passwords":
If you really want to protect against attacks, make sure you use salt in the digest; if it's a well-known algorithm like MD5, and someone can get hold of the hash output, then on their own CPU time they can rapidly check against possible passwords and if they find a match then they've got the password. Adding salt prevents this kind of attack (see the wikipedia article).
You might try looking at OpenID as it's a fairly straightforward means of handling authentication. Well-known sites (OpenID providers) handle the authentication for you, and cryptographically assert that the person with identity X has properly authenticated. Then you just need to handle the authorization of which identities X are allowed to do what. You can always restrict which identity providers you trust (e.g. you might trust Yahoo and AOL and Blogger but not some random site since anyone technically can host their own identity provider server).