Secure OpenID user authentication - security

My goal is a secure login in system such as stackoverflow uses. I am a newbie but as you have probably seen I have spent all day looking up stackoverflow articles on security. As a result of this research I have now worked out a plan of attack. In particular this page was a great help Using OpenID for website Authentication. Can you please tell me if the following system would be a secure system and if not how should I improve the system.
Use OpenID to validate users.
Once a user has been validated by OpenID get user's email address from OpenID.
Hash the email address and store in session variable.
Compare Hashed email address to list of hashed email addresses in databases
Return content appropriate to that user based on the hashed email address.
In particular I am nervous about using the email address instead of the ProviderOpenID.
Please assume that I have (as I have found answers to these questions on other stackoverflow pages):
Properly destroyed sessions after use.
Setup my server to store session data in an inaccessible location.
Setup my database in a secure manner.
I am using SSL to ensure traffic cannot be intercepted.
Thanks in advance.

In general, your way better of using some authentication architecture for the language you are using that supports OpenID. Not only is it more secure, its just easier, you write less code, and you don't have to maintain that code or test it. There are ones for PHP,python,c#/asp.net, rails. A lot of frameworks also have support.
First, why not use the provided ID ?
I think you have two problems:
Its possible that an openID provider could return a email address for a different domain than the provider's.
For example, gmail could authenticate me correctly but I could specify that my email address was billg#microsoft.com. Then you would read my identity as me being Bill Gates despite the fact that it is not. There are of course ways to prevent this, but the standard system probably has safeguards included and even if it doesn't, it is someone else's responsibility to fix them and other people will be looking at those issues.
If I am reading the wikipedia article correctly, openID id's are not necessarily email addresses
This is not a security problem , but it does break expected behavior.

Related

Secure web programming - Best practises in authenticating users

Getting into web development and would like to become good at making secure websites. Any general typs/answers to any of the below would be greatly appreciated.
So got some questions on the authentication side of things:
How should the password typed on the client be encoded and sent to the server - assuming https is already in use? i have heard of some suggesting that only the hash is sent for security for example. Should it be encrypted client side - how?
Similar but on server side. How should the passwords be saved. Actual, hash, etc? Should they be encrypted - how?
Also, is there a kind of architecture that can protect the passwords in such a way that if one password is compromised, not everyone else's is? For example, if all passwords are stored in one file then access to only this one file would compromise every user on the system.
if only hashes must be stored - how to handle collisions?
Once authenticated should you just rely on session IDs to maintain authenticated status throughout? I have read on tips to reduce session highjacking and was therefore wondering whether it is a good idea/the only idea in the first place for keeping users authenticated.
Is there a safe way to provide an autoLogIn feature so that the browser remembers the password - similar to social network/web-email clients?
-------------
Extra - preventing attacks
Are there any tools or even just some common practises out there that must be applied to the username/password entries provided to prevent injection or any other kind of attacks?
If I use a Java development environment (using PlayFrameWork btw) how likely is it in general that attackers could include harmful code snippets of any kind in any form entries?
PS
As mentioned I will probably be using the Java PlayFrameWork to encode the website - can you suggest anything I should take into account for this?
Any tips on design patterns that must be followed for security purposes would be helpful.
Many Thanks
PPS
You could suggest passing the job on to an expert but if possible I would like to have some experience coding it myself. I hope that this is a viable option?
Will probably like to set up an e-commerce system FYI.
How should the password typed on the client be encoded and sent to the server - assuming https is already in use? i have heard of some suggesting that only the hash is sent for security for example. Should it be encrypted client side - how?
It should not be sent to the server in a way that can be recovered. The problem with SSL/TLS and PKI is the {username, password} (or {username, hash(password)}) is presented to nearly any server that answers with a certificate. That server could be good or bad.
The problem here is channel setup is disjoint from user authentication, and web developers and server administrators then do dumb things like put a plain text password on the wire in a basic_auth scheme.
Its better to integrate SSL/TLS channel setup with authentication. That's called channel binding. Its provides mutual authentication and does not do dumb things like put a {username, password} on the wire so it can be easily recovered.
SSL/TLS offers nearly 80 cipher suites that don't do the dumb {username, password} on the wire. They are Preshared Key (PSK) and Secure Remote Password (SRP). Even if a bad guy answers (i.e., controls the server), the attacker cannot learn the password because its not put on the wire for recovery. Instead, he will have to break AES (for PSK) or solve the Discrete Log problem (for SRP).
All of this is covered in great detail in Peter Gutmann's Engineering Security book.
Similar but on server side. How should the passwords be saved. Actual, hash, etc? Should they be encrypted - how?
See the Secure Password Storage Cheat Sheet and Secure Password Storage paper John Steven wrote for OWASP. It takes you through the entire threat model, and explains why things are done in particular ways.
Once authenticated should you just rely on session IDs to maintain authenticated status throughout?
Yes, but authorization is different than authentication.
Authentication is a "coarse grained" entitlement. It asks the question, "can a user use this application?". Authorization is a "fine grained" entitlement. It answers the question, "can a user access this resource?".
Is there a safe way to provide an autoLogIn feature so that the browser remembers the password - similar to social network/web-email clients
It depends on what you consider safe and what's in the threat model. If your threat model does not include an attacker who has physical access to a user's computer or device, then its probably "safe" by most standards.
If the attacker has access to a computer or device, and the user does not protect it with a password or pin, then its probably not considered "safe".
Are there any tools or even just some common practises out there that must be applied to the username/password entries provided to prevent injection or any other kind of attacks?
Yes, user login suffers injections. So you can perform some filtering on the way in, but you must perform HTML encoding on the output.
Its not just username/password and logins. Nearly everything should have some input filtering; and it must have output encoding in case its malicious.
You should definitely spend so time on the OWASP web site. If you have a local chapter, you might even consider attending meetings. You will learn a lot, and meet a lot of awesome people.
If I use a Java development environment (using PlayFrameWork btw) how likely is it in general that attackers could include harmful code snippets of any kind in any form entries?
Java is a hacker's delight. Quality and security has really dropped since Oracle bought it from Sun. The more paranoid (security conscious?) folks recommend not signing any Java code because the sandbox is so broken. That keeps a legitimate application properly sandboxed. From http://threatpost.com/javas-losing-security-legacy:
...
“The sandbox is a huge problem for Oracle,” Jongerius told Threatpost.
“Everyone is breaking in. Their solution is to code-sign and get out
of the sandbox. But then, you have full permission to the machine. It
doesn’t make sense.”
Its too bad the bad guys didn't get the memo. They sign their code the malware and break out of the sandbox.
Any tips on design patterns that must be followed for security purposes would be helpful.
You also have web server configurations, like HTTPS Only and Secure cookies, HTTP Strict Transport Security (HSTS), and Content Security Policies (CSP), Suhosin (hardened PHP), SSL/TLS algorithms, and the like.
There's a lot to it, and you will need to find the appropriate hardening guide.

Security concerns regarding username / password vs secret URL

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.

Password Recorevy Without email

I was wondering if anyone has ever used, built or seen a password recoervy tool that was completely online and didn't require sending some kind of password reset email.
I understand the security concerns and I am completely open to the idea that this is just not a secure way to handle things but I have been tasked by my employer to look into this type of solution. I feel like I have used something like this before.
Our main concern is email spam filters grabbing lost password emails. If there were best practices on formatting these emails that would be a great thing to send over also.
Any thoughts?
THanks
Craig
Almost all security relies on varying combinations of the three things below
Crypto-graphic proof
shared secret
trusted third party
and using them, for a given level of likelihood, to verify that the counter-party in the current transaction, is the same party with whom you had the original contract.
Really thats all "online identity" is - how likely is it that the person talking to me now is the person I was introduced to yesterday.
For example, a password is a shared secret, that both parties know and assume for a given level of likelihood that the other person with the secret is who they think they are.
Thats the easy one.
The security question (Mother's Maiden name) is just a second password in case you forget the first.
OpenID is a trusted third party approach. Stackoverflow trusts google. I try to login to
stackoverflow and SO passes me over to google. All SO sees is google coming back saying "yes he is".
However, compared to email penetration, OpenID is hardly used, so its not going to work as recovery option.
The email password reset is an example of a direct shared secret involving a trusted third party - gmail is "trusted" by both parties, so one can send a shared secret to gmail, and trust that for a given level of likelihood, only the other party will be able to access that shared secret.
Finally cryptography can be used as a trusted third party. If I know your public key I can "trust" RSA and store the new password by encrypting it then putting it on my website. Only you can read it, so it could work as an instant, online password reset. But the penetration of PGP/GPG is so much worse than that of OpenID the idea is a non-starter (*)
What you need is a second channel of communication that you gather at the time of contract - usually it email, it could be openid, a mobile number or their GPG public key.
But you must collect that channel at the time of making initial contract.
Talking of mobiles, I did see a neat one at my local cellphone shop - they texted me a random password, and then the sales assisstant entered in the password when it arrived at my phone - proving the phones owner was in the shop and compliant. (for a given level of likelihood).
(*) actually I think there is a solution - http://www.itmanagerscookbook.com/Attitude/identitycrisis.html. AS you can tell trying to express the concepts above is an ongoing effort.
The only safe alternative I'm aware of is offering a password reset page after a security question (mothers maiden name, but preferably something user configurable/safer).

Commonly used solutions for credential caching?

I have question about credential caching in applications. I've searched around on the net for solutions to this problem, but I haven't found anything (which is really surprising, since this is something that every Facebook, Twitter, and email client application has to deal with).
My question is this:
Let's say I'm building some simple Twitter client. I don't want to force the user to enter their password every time. How do most applications tackle this problem? At some point, the client needs to make an API call to authenticate (which includes the password, which is usually in plain text). However, saving the password in plain text somewhere not the correct solution, obviously. So, how do most apps do this safely? I suppose you could cache the password in a file or db if the password is encrypted, but then how do you safely store the decryption key? Or is it generated at runtime using unique information from the client machine as a seed?
Are there any resources (articles, books, etc.) that talk about this? How do most apps handle this?
Thanks!
Single-sign-on (SSO) setups accomplish what you describe typically by providing centralized methods to generate, distribute and validate a key using some type of session ID.
See for one method (used by StackExchange/StackOverflow):
http://openid.org/
Here's something I didn't know: This category of functionality is known as Federated Identity. For instance, our web system where I work offers (but doesn't require) Shibboleth. See here for a list of options:
http://en.wikipedia.org/wiki/Category:Federated_identity

What's a good alternative to security questions? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
From Wired magazine:
...the Palin hack didn't require any
real skill. Instead, the hacker simply
reset Palin's password using her
birthdate, ZIP code and information
about where she met her spouse -- the
security question on her Yahoo
account, which was answered (Wasilla
High) by a simple Google search.
We cannot trust such security questions to reset forgotten passwords.
How do you design a better system?
The insecurity of so-called "security questions" has been known for a long time. As Bruce Schneier puts it:
The result is the normal security protocol (passwords) falls back to a much less secure protocol (secret questions). And the security of the entire system suffers.
What can one do? My usual technique is to type a completely random answer -- I madly slap at my keyboard for a few seconds -- and then forget about it. This ensures that some attacker can't bypass my password and try to guess the answer to my secret question, but is pretty unpleasant if I forget my password. The one time this happened to me, I had to call the company to get my password and question reset. (Honestly, I don't remember how I authenticated myself to the customer service rep at the other end of the phone line.)
I think the better technique is to just send an e-mail with a link they can use to generate a new random password to the e-mail account the user originally used to register. If they didn't request a new password, they can just ignore it and keep using their old one. As others have pointed out, this wouldn't necessarily have helped Yahoo, since they were running an e-mail service, but for most other services e-mail is a decent authentication measure (in effect, you foist the authentication problem off on the user's e-mail provider).
Of course, you could just use OpenID.
Out-of-band communication is the way to go.
For instance, sending a temporary password in SMS may be acceptable (depending on the system). I've seen this implemented often by telecoms, where SMS is cheap/free/part of business, and the user's cellphone number is pre-registered...
Banks often require a phone call to/from a specific number, but I personally am not too crazy about that....
And of course, depending on the system, forcing the user to come in to the branch office to personally identify themselves can also work (just royally annoy the user).
Bottom line, DON'T create a weaker channel to bypass the strong password requirements.
Having seen a lot of posters suggest email, all I can suggest is DONT use email as your line of defense.
Compromising somebodys email account can be relatively easy. Many web based email services DONT provide any real security either, and even if they offer SSL, its often not default and you are still relying on the weakness of the email password to protect the user ( Which, in turn has a reset mechanism most the time ).
Email is one of the most insecure technologies, and there are good reasons why its a really bad idea to send information like credit card details over them. They're usually transmitted between servers in plaintext, and equally often, between server and desktop client equally unencrypted, and all it takes is a wire sniff to get the reset url and trigger it. ( Don't say I'm paranoid, because banks use SSL encryption for a good reason. How can you trust the 20-200 physical devices on the route have good intentions? )
Once you get the reset data, you can reset the password, and then change your(their) email address, and have permanent control of their account ( it happens all the time ).
And if they get your email account, all they have to do is have a browse through your inbox to find whom you're subscribed with, and then easily reset the password ON ALL OF THEM
So now, using the email based security, can lead to a propogative security weakness!. I'm sure thats beneficial!.
The question being asked Is one I figure is almost impossible to do with software alone. This is why we have 2-factor authentication with hardware dongles that respond to challenges with their own unique private key signature, and only if you lose that are you screwed, and you then have to deal with a human ( oh no ) to get a new one.
It 'depends' on the 'system'.
If you are a Bank or a credit card provider, you have already issued
some physical token to your customer that you can validate against and more.
If you are an ecommerce site, you ask for some recent transactions
-exact amounts, credit card number used et al..
If you are like Yahoo, an automated approach I would use is to send an
activation code via either a phone call or a text message to the cell
phone along with some other basic question and answers.
Jay
Do away with the (in)security questions completely. They're such an obvious security hole that I'm actually a bit surprised that it's taken this long for them to create a serious (well, highly-publicized) incident.
Until they disappear, I'm just going to keep on telling websites which use them that I went to "n4weu6vyeli4u5t" high school...
Have the user enter 3 questions and answers. When they request a reset present them with a drop down of 5 questions, one if which is a random one from the 3 they entered. Then send a confirmation email to actually reset the password.
Of course, nothing is going to be truly "hacker proof".
When users are involved (and mostly when not, too) there is no security; there is only the illusion of security. There's not a lot you can do about it. You could have 'less common' security questions but even they are prone to exploitation since some people put everything out in the public eye.
Secondary channels like email offer a reasonable solution to the problem. If the user requests a password reset you can email them a password reset token. Still not perfect, as others have said, but exploiting this would require the attacker to be somewhere in the line of sight between the website, its MTA and the users MUA. It's technically easy but I suggest that the reality is it's just too much work/risk for them to bother on anyone except very high profile individuals.
Requiring the user to supply SSL or GPG public keys at account creation time will help enormously, but clueless users won't know what those things are let-alone be able to keep their private keys secure and backed up so they don't lose them.
Asking the user to supply a second emergency password (kind of like PIN/PUK on mobile phone SIM cards) could help but it's likely the user would use the same password twice or forget the second password too.
Short answer, you're S.O.L unless you want to educate your users on security and then hit them with a cluestick until they realise that it is necessary to be secure and the slight amount of extra work is not simply there to be a pain in the arse.
Authenticating everything by sending emails is a reasonably effective solution. (although, that might not have been workable for Yahoo in this case :)).
Rather than messing about with security questions or other means to recover passwords, simply respond to password recover requests by sending an email to a predefined email account with an authorisation link. From there you can change passwords, or whatever you need to do (never SEND the password though - you should always store it as a salted hash anyway, always change it. Then if the email account has ben compromised, at least there's some indication to the user that their other services have been accessed)
The true answer is, there isn't a fool proof way to keep hackers out. I hate security questions, but if your going to use them, allow for user defined security questions. As a user, if I must have a security question on a site to set up an account, I really like having the ability to setup my own security question to allow me to ask something that only I know how to answer. It doesn't even have to be a real question in this case. But a users account is then as secure as the stupidity of the user, and the fact that many users will use something like "question?" and "answer!" or something equally dumb. You can't save users from their own stupidity.
Treating these security questions as something actually being two-factor authentication is totally misleading. From spurious items read before, when certain (banks) sites were required to have "two-factor authentication" they started implementing this as a cheap way to do it. Bruce Schneier talked about this a [while back][1].
Multiple factors are best things that are not-the-same. It should not be all things you "know" but something you know and something you have, etc. This is where the hardware authentication tokens, smart cards, and other such devices come into play.
[1]: http://www.schneier.com/blog/archives/2005/03/the_failure_of.html The Failure of Two-Factor Authentication
when its not an email system, email them a link to a secure page, with a hash that must come back in the query string to reset password.
Then if someone tried to reset your password, you would know, and they wouldn't be able to guess the hash potentially.
We use 2 guids multiplied together, represented as hex.
Well for one it should not directly reset the password but send an email with a link to reset the password. That way she would have got the email and known that it was not her who initiated the reset, and that her question / answer had been compromised.
In the case where the email address is no longer valid, it should wait for a timeout ( few days or a week ) before allowing a new email to be attached to an account.
Send a message to a different e-mail account, or text their cell phone, or call them, or send a snail-mail message. Anything that doesn't involve matters of public record or preferences that may change at any time.
Good security questions are a misnomer. They actually create a vulnerability into a system. We should call them in-secure questions. However, recognizing the risk and value they provide, "good" security questions should have 4 characteristics:
1. cannot be easily guessed or researched (safe),
2. doesn't change over time (stable),
3. is memorable,
4. is definitive or simple.
You can read more about this at http://www.goodsecurityquestions.com.
Here's a list of good, fair, and poor security questions.
IMO Secret questions should only be used as a very weak control with a time limit as part of a system.
Ex: Password reset system.
You are authenticated. Registrate your mobile phone number and your secret(not so secret) answer.
You forget your password.
You request to unlock it.
a) Your "Not so secret" question asks you for the "not so secret answer".
b) If correct, a text message is sent to the pre registrated phone.
This way, if your phone gets stolen and also, controls like pin/lock on the phone is not working. You still will have a measure of obfuscation for the attacker to get to reset the password until the time it is reported the phone is lost/stolen and can be disabled.
This usage is what i think the only purpose at all for the "not so secret" questions/answers.
So i would argue there is a place in this world for them and that usually a system needs to be the discussion.
Only provide questions that aren't on the public record.
always send the password reset to a registered email account (which is tricky for an email account) or send a PIN number to a registerd mobile phone, or a link to a IM address, etc - basically, capture some secondary contact information on registration and use it to send a 'password reset' link.
Never let anyone change their password directly, always make sure they go through an additional step.
I prefer to keep things simple and use an honor system approach. For example I'll present the user with something like,
Is this really you? Select: Yes or No.
How about requesting the users to enter their own security question and answer, and a secondary email (not the one where the password reset link is sent). Store the security question and answer hashed in the database for that extra step of security.
If the user forgets his/her password, send the password reset link to the user's primary email.
User then clicks on the link which redirects and asks for the security question and answer. If this step is successful then allow the user to reset his/her password. If the user forgets the security question/answer send a link to reset the security question/answer to the user's secondary email.
If the attacker gets access to one of the emails, it will still be useless without access to the other (very unlikely the attacker can get access to both). I know this process needs a lot of extra work on both the developers and users, but I think it is worth it. (Maybe we could give the users a recommended option to activate the security question/answer if they need this extra bit of security.)
Bottom line is that how strong or weak this system works will depends heavily on the user. The strength of the security question/answer and how well the two emails are "untied" (that is, there is no way of gaining access to one email through the other) will decide this systems strength.
I don't know if there are any problems with this way of doing it, but if any, I'd be happy if anyone could point those out :)
Generate a hash that contains the person's username and password and send it over Https to the user as a file. The user saves the file to disk. It is their responsibility to store this file in a secure location. Alternatively you can send it to their email address but this will result in less security. If the user forgets their login credentials they must then upload this file. Once the server verifies the username and password, they are then presented with a dialog to alter their password.
Due to the evolution of social media, security questions asked by websites are too easy to crack. Since most of the questions are personal information which is easily available on social media platforms one or another. One of the alternatives to avoid account hacking is to make password rules strict for login like adding special characters, numerical, capital letters etc. These kind of passwords are hard to decode and can enhance the security to a great extent.
But there are new alternative methods like multi-factor authentication, passwordless login, SMS authentication etc. SMS authentication is part of multi-factor authentication where a user is provided with an OTP on his/her cellphone which he/she need to enter in order to log in to a website. This is a secure way since the access of mobile is limited to the user only(mostly). Another multi-factor authentication method is sending a verification link to email to complete the signing in process. There is a very well written blog on this topic on Medium that explains this concept in a detailed manner.

Resources