I am storing OpenIDs into a database so I can log in users very quickly. Should I be encrypting them in my database?
An alternative question would be, are they considered 'sensitive' information?
Contrary to another answer: No. There's no point in doing it.
To get access to an account, one must first authenticate with the OP. There is no method to somehow break into someone's account by simply knowing an identifier (and only that).
The OpenID protocol, by design, allows users to place their identifiers in very obvious places (like their homepage) with little additional risk. If identifiers were meant to be 'sensitive' information, it wouldn't be possible to delegate OpenIDs.
If the fact that your database has been compromised would imply that an attacker has access to all the identities, OpenID would be really, really insecure (and it isn't).
The OpenID identifier is only a url pointing at a provider. From this information, you can't infer anything more than who the user claims to be (and in case of directed identity, not even that).
You could ask yourself: "Should I be encrypting logins?"
If your answer is true -- encrypt the identifiers, because they are no different.
If it's false, then don't bother.
Related
I recently stumbled across this article on securing Web API endpoints.
If I'm using SSL, is there any advantage to encrypting the user string in the header? What are the risks if I include the user key (Id) as plaintext instead of ciphertext?
TLS is transport-level security. I.e. the data is not secured by TLS before the data reaches the transport and after that. If your data is long-term and/or you keep them elsewhere besides using during the transport session, then it might make some sense to keep them encrypted (and then transfer them encrypted if possible). If your data lifetime is short and the data makes sense only during the transport session, then there's no much sense in encrypting the data besides TLS.
The author of the article is basically combining the concepts of a user identifier and a user secret into a single cryptographic token. If you choose to send a user identifier in plaintext instead, then that user identifier must be kept secret (just as the token must be kept secret). As long as that secrecy is maintained there is no advantage to using the token.
Note that this system doesn't seem very secure as presented. If an attacker can guess a valid user identifier then they can generate a valid token. The author is basically using RSA as a glorified hash function. I'd recommend you look for another reference.
I just read an article saying that passwords with 7 characters are no longer safe. However, if the server increases the time to retry a login attempt after each login attempt, then brute force attacks are useless. How do you create such logic in asp.net? Somehow I guess the server side code needs to remember the ip-address that tried to login and should increase the response time with each new try?
IP address isn't really a secure method of identifying the user. You could try storing the last time a login attempt was submitted in a cookie, but if the browser doesn't accept them, it'll be of limited use. Session variables also require cookies, so they're out.
Some sites (yahoo comes to mind) start showing a Captcha form after the third or so attempt. You have to correctly answer the captcha in addition to your login details.
Another option would be to disable an account after X failed attempts (which can be tracked in your database), but I personally dislike this as it tends to force me to call someone to get my password reset whenever I forget one.
Many brute force attacks occur offline. That's why failed-attempt lock-outs are no substitute for requiring complex passwords, using proper "salt", and key-strengthening.
ASP.NET has a built-in mechanism to prevent brute force attacks against login passwords.
Refer to the maxInvalidPasswordAttempts Membership property.
IMHO 7 character passwords are perfectly adequate for most web applications (my bank allows 7 char passwords) provided security best practices are followed, such as securely hashing passwords and blocking brute force attacks.
Once you get beyond 7 or 8 character passwords, you are really saying "my app needs to be super secure", in which case you ought to consider individual client SSL certificates. Requiring more characters in a password has diminishing returns. How many of your users can remember complex 8 or 9 character passwords? They end up writing them down. Personally, I get turned away by any site that requires me to create some super-complex password.
ASP.NET Membership does most of the hard work around security for you, as long as it is setup properly.
However, there are some things ASP.NET Membership cannot do for you, such as:
Ensuring HTTPS is used
Preventing CSRF and similar attacks
Ensuring all web requests are routed to ASP.NET to prevent static content being served up by IIS and bypassing ASP.NET authentication
Checking that the user is a human (CAPTCHA)
For more on security best practices I'd look at OWASP
There appear to be at least three attacks you might want to worry about:
Targeted attack at a particular user. You want to make logging in more difficult for the attackee, but not too much more difficult. A CAPTCHA is sufficient (but don't make the user type in the password again if it wasn't displayed on the login page).
Large-scale attack on many users. Locking out individual users is a bit pointless, since the attacker can just try (say) 3 passwords and then move on to a different account. A CAPTCHA per IP might be sufficient, but you may also want to rate-limit per-IP (or X-Forwarded-For for a list of whitelisted proxies). This depends on the size of your attacker's botnet; a large enough botnet can distribute attacks over multiple bots/sites such that each site gets a low rate from each IP.
Offline attack on the password database. In this case, you need at least about 50 bits of entropy even with a good hash (NTLM uses a single call of MD4 which is not a good hash), which you can't get in a relatively normal 8-character password (8 log2(94) is only 52.4).
You could store tries-per-IP into a tree, where you group dense parts of the tree together. Then just bucketize it (construct a new tree every 10 minutes, keep the old tree around for 10 more minutes). This has the possibly mistaken assumption that neighbouring IPs are likely to exhibit similar behaviour, but downgrades gracefully into just clustering the IPv4 into (say) /24's.
If you're feeling particularly generous, you can store a separate cookie on login that's not cleared on logout, and save a copy in the database (a 128-bit random value should be good enough). On a login attempt, be "nicer" to the browser if it presents the correct cookie (e.g. allow 3 attempts on that cookie without counting per-IP or per-user failure rate). This means that the last machine used to access the account isn't presented with a CAPTCHA even when the user's account is being bruteforced.
In general, it's more useful to talk about password entropy than password length and "types of characters" — I'm pretty sure nearly everyone just makes the first letter capital and sticks a 1 on the end. I've also yet to see any "human-friendly" password generators that also state password entropy.
I am looking for something that takes an IIS/ASP.NET website that uses forms authentication and repeatedly tries to login, either with all possible passwords or with passwords from a dictionary.
I can probably write something up, but I wondered if there was anything publicly available that would be better implemented.
For online brute forcing of login systems I recommend using THC-Hydra. I always use this tool in my penetration tests. By contrast if you have a password hash or a salted password hash then you should use John The Ripper to break it offline which is much faster.
After 3 failed logins you should prompt that ip address with a captcha like reCaptcha.
If you're using the built-in ASP.NET membership provider, there's a property you can set called passwordAttemptThreshold. After a certain number of attempts the account will automatically be locked. While you can still be brute-force attacked, the chances of an account being compromised within the passwordAttemptThreshold is sufficiently low. Also, you can enforce a password policy with the membership provider as well, which really makes brute-force attacks less likely.
Granted, this doesn't answer your exact question, however you may still find it more prudent to simply prevent brute-force attacks from happening in the first place. Whatever brute-force library you find, there will always be a better one out there - and the good ones probably aren't even available as they are no doubt a closely-guarded secret of real hackers.
Instead of attacking the website from the outside, I would recommend taking the hashes and cracking them offline.
A better approach is to make a password policy on the site so you don't have to do this. Password cracking is tough, and unnecessary in most situations
I have 2 sites that are on different servers and domains but I would like to pass from one to the other with out having to re-authenticate.
Both sites use the same DB so my thought was have an Auth Table where I place a GUID, the users ID, and a time stamp. I would pass the GUID in the URL and do a lookup to see if the GUID is in the table and is less then X old, if so authenticated the user.
Any thoughts?
Yes, As long as security is not critical in your solution.
If security is critical (money is involved) some other measures should be added.
like - encrypt the guid or pass it over secure connection -so it can't be stolen
have the guid used only once (to avoid replay attacks, and constantly look for holes in this system, as you implement your own security.
encryption is not easy as you need a key, and if you choose bad keys, or store them not good, the encryption is useless.
knowing more about the architecture, clients might help tightening the security some more.
Remember that passing it as part of the URL leaves a trail all over the web with the guid. Maybe there is a better way to pass it, maybe as data.
The secure way to do this would be to use OpenID with Directed Identity.
This way the first site can assert the identity of the user that is accessing the second site.
Asp.net stores the session in a cookie, thus not having to worry about sessions on the server side (traditionally sessions are stored in a database, and lookups are done via a session ID, which is usually a Guid like string).
In my previous question, I was asking about how a spring application stores/creates sessions etc: Spring authentication, does it use encrypted cookies?
Cletus pointed out that storing a username/id in a cookie, although encrypted, is a security issue because the would-be-hacker has both the encrypted text, but also the hacker knows what the actual encrypted text is i.e. the userId or username.
What are you thoughts on this?
I am sure StackOverflow is also using this mechanism, as is **99.9% of asp.net web applications that are using formsauthentication in this manner.
Microsoft's MSDN site itself is filled with examples like:
FormsAuthentication.RedirectFromLoginPage(UsernameTextbox.Text, NotPublicCheckBox.Checked);
In the above code, the username value is stored in the encrypted cookie.
actually, I recall that the asp.net website was hacked because the web.config didn't have the Protection=All in the forms authentication tag.
So is this a real issue?
To repeat what cletus linked to:
In case you're wondering what a "crib" is. see: http://www.faqs.org/faqs/cryptography-faq/part03/
Cryptanalytic methods include what is
known as practical cryptanalysis'':
the enemy doesn't have to just stare
at your ciphertext until he figures
out the plaintext. For instance, he
might assumecribs''---stretches of
probable plaintext. If the crib is
correct then he might be able to
deduce the key and then decipher the
rest of the message. Or he might
exploit ``isologs''---the same
plaintext enciphered in several
cryptosystems or several keys. Thus he
might obtain solutions even when
cryptanalytic theory says he doesn't
have a chance.**
Maybe you should take a look into this document: Improving Web Application Security: Threats and Countermeasures -- Threat Modeling
It's a good start point to understand what security risks are involved and how can you mitigate that threats.