Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Anders Bjerner 487 posts 2989 karma points MVP 7x admin c-trib
    May 26, 2014 @ 13:14
    Anders Bjerner
    1

    Questions regarding how Umbraco stores and hashes passwords

    Let me start with saying that I'm not a security expert, and I don't know what thoughts the HQ have had on how passwords are currently stored in Umbraco. That being said, I have some security concerns on how Umbraco stores passwords. These concerns only applies IF a potential hacker (the evil kind) should get access to an Umbraco database.

    By default Umbraco will store passwords using HMACSHA1 - a hashing algorithm that takes two inputs (a key and a value) to produce a single output, that then is stored the database. HMACSHA1 isn't necessarily a bad for storing passwords, but it also has some drawbacks, including the way it is used in Umbraco.



    From what I can understand the idea of storing passwords using HMACSHA1 is to have a different key and value to make the stored hashed less predictable.

    Umbraco uses the password of the user as both the key and the value making password more predictable. Below is a reference to the old Member.cs from Umbraco 4, but Umbraco 7 appears to be storing password the same way.

    https://github.com/umbraco/Umbraco-CMS/blob/82c1c95e357e4f64df4fd441175997013c077734/src/umbraco.cms/businesslogic/member/Member.cs#L1264

    If my password is bacon (because, who wouldn't?) the stored hash will be FfEajy0CHVkzTSqZPXRBMZIGndc=. The hash will always be this value for bacon - across all Umbraco installations. And if two users have the password bacon, they will have the same hash in the database.

    If we consider that I'm a hacker with access to the database, and that I now the stored hash is FfEajy0CHVkzTSqZPXRBMZIGndc=, it will take me less than a minute to brute force the password using an eight-core CPU that is a few years old. Of course as the passwords gets longer and more complex (numbers, special characters etc.), the more time will it take to crack a given password using brute force. But then again, newer CPUs will be faster, and GPUs should be even faster. And CPUs/GPU's will be even faster in the future.

    Another way to crack passwords is two use rainbow tables (not the unicorn kind of rainbow that we adore). A rainbow table is a collection of all password combinations (to a certain length, certain characters etc.) typically having the size of several gigabytes if not hundreds of gigabytes. If you know where to look, rainbow tables can be downloaded for most popular hashing algorithms. I don't know if there is rainbow table for Umbraco, but since Umbraco hashes passwords in a predictable way, a patient hacker would be able to create one himself. With a rainbow table for Umbraco in hand, it would just be to lookup a specific hash, and then see the password of the user.



    A way to prevent attacks using rainbow tables is to use salts - typically a random value that is stored along with the password, and then used as the key when hashing the password (value). This will make the stored hashes less predictable, and users with the same password should in theory always have different hashes. Using salts will however not protect against brute force attacks since the hacker will also now the salt, since he has access to the database.

    Hashing a single password using HMACSHA1 will take less than 10 milliseconds on my computer. The speed is one of the reasons brute force attacks are possible. So time is really the best defence.

    Instead of HMACSHA1 there are some algorithms that by design will take a lot longer to hash a given password - an example of such an algorithm is bcrypt ( http://en.wikipedia.org/wiki/Bcrypt ). bcrypt works in cycles, so if a single cycle will take 50 milliseconds (just an example), two cycles will take roughly 100 milliseconds (twice as long). And the more cycles, the longer will the hashing take. And as computers get faster - just add some more cycles. So since we could use enough cycles for it to take half a second for hashing a single password, it would not be possible to use a brute force attack to crack a given hash. bcrypt also incorporates salts, so it will prevent rainbow table attacks as well.



    I'm not saying Umbraco should totally use bcrypt because it is more secure than HMACSHA1, but I'd like to hear the thoughts that the HQ have had about this.

    There are also some alternatives to bcrypt - for instance StackOverflow has switched from bcrypt to PBKDF2 since there isn't a verified implementation of bcrypt for .NET, but .NET ships with PBKDF2 (from what I can understand).



    Some useful references:

  • Sebastiaan Janssen 5045 posts 15476 karma points MVP admin hq
    May 26, 2014 @ 14:20
    Sebastiaan Janssen
    1

    In the new membership provider (6.2.0+, 7.1.0+) we're still using HMACSHA1 but with a separate salt that is different on each machine the hashing is done. Moreover, every time a password is generated it is a completely new and unique string, so no rainbow table vulnerability exists any more. We believe this to be more than adequate and this is very hard to crack with any "normal" hardware (to be honest, I haven't looked into how hard it would be to crack using a botnet or something but I think the effort would be significant).
    The new password encryption algorithm is following Microsoft's recommendations for a sql membership provider.

    If you're still concerned, then you can set hashAlgorithmType in the member ship provider's configuration to deviate from HMACSHA1 (see http://stackoverflow.com/questions/1137368/what-is-default-hash-algorithm-that-asp-net-membership-uses for defaults and supported types) or implement your own membership provider (Umbraco's version is just an implementation of a normal .net membership provider) and use any encryption algorithm that you think is sufficient. In fact this was always a possibility even in v4 and v6.

    Umbraco 6.2.0+/7.1.0+ still ship with the legacy encoding by default to maintain backwards compatibility (switching it over would immediately break any current logins).

  • Anders Bjerner 487 posts 2989 karma points MVP 7x admin c-trib
    May 26, 2014 @ 23:59
    Anders Bjerner
    0

    Thanks a lot for your answer. I didn't know there were any changes to this with the new membership provider. I glad to see that it takes care of the possibility for rainbow table attacks. Do you have more information on how to use the provider with the new changes?

    My questions were mostly to find out the thoughts you have had on this. I don't think the changes solve the problems with brute force attacks, but as you point out, it shouldn't be feasible with normal hardware - at least if the user has a complex password. But still - it is probably fine for most Umbraco installations (and a hacker would need access to the database first). If not new membership provider isn't enough, one could implement a custom provider as you also point out.

  • Sebastiaan Janssen 5045 posts 15476 karma points MVP admin hq
    May 27, 2014 @ 15:16
    Sebastiaan Janssen
    1

    Update to the new provider in web.config (default in all new installations) and update useLegacyEncoding to false, but only do that if you don't have existing users (so before you install Umbraco) else you won't be able to log in with existing users any more.

    I think brute force will never be solved when the database is exposed, but currently the new provider causes anybody to try and log in with the wrong credentials 5 times to be locked out completely so without access to the database things are much more secure already (this already works for all 6.2.0+/7.1.0+ sites that have changed the membership provider in web.config to the new version).

  • Shannon Deminick 1524 posts 5270 karma points MVP 2x
    May 28, 2014 @ 01:18
    Shannon Deminick
    1

    As Sebastian mentions, the new membership providers deal with storing passwords differently. It's worth noting that before .Net 4.0 the default hashing algorithm was HMACSHA1, it is now HMACSHA256 which is far stronger.

    The previous membership hashing implementation was not ideal, as you've noted, because the key used in the HMACSHA1 was guessable. Another issue with the previous provider was that you couldn't configure the algorithm, it ignored the algorithm type specified in config and always used HMACSHA1. This has all changed with the new providers. We respect the algorithm type specified and we use the built in .Net functionality to do the hashing which is based on your machine key. If you don't specify a custom machine key (but you should) then the chances of your site using the same machine key as another are probable. This is because a machine key is auto-created based on the path of your website (normally just '/' but this is also configurable). If you want some light reading on that subject here you go :

    The new membership providers use a randomly generated salt for each password. If the database is compromised a hacker cannot just crack one password and use that same mechanism to crack them all, they would have to individually crack each password. The logic used in the new membership providers for password storage is near identical to the logic used in Microsoft's SqlMembershipProvider (.Net 4.5)

    For the new providers, when useLegacyEncoding=true, the legacy logic is used - this is for backwards compatibility. You cannot simply upgrade your existing config because the hashing is entirely different and your members/users won't be able to login. If you wanted to upgrade you would have to deal with this in some custom way (i.e. like bulk resetting everyone's password, sending out an edm with a link for people to enter a new one, or something along those lines).

    Also note that you cannot just go changing a machine key of a website once you have data that is hashed in the database because again the hashing key will no longer match.

  • Gordon Saxby 1444 posts 1855 karma points
    Aug 26, 2015 @ 08:49
    Gordon Saxby
    0

    Does using the new provider (with useLegacyEncoding=false) mean that you can't copy an Umbraco DB from one machine to another, because the machine key would be different?

    Would it be OK if you specified a machine key in the website web.config?

  • Shannon Deminick 1524 posts 5270 karma points MVP 2x
    Aug 26, 2015 @ 09:21
    Shannon Deminick
    0

    @Gordon, machine keys really depend on your infrastructure and your machine key settings. How default machine keys are generated are based on a few factors and can also be set at the machine config level. In many cases, you'll probably end up using the same generated machine key if you don't specify one so long as your setup between environments is the same... however it would be much much safer for you to generate a machine key for your site and use that. That way your site is fully portable to any infrastructure. IMO it's best to always use a custom machine key for your sites:

    • Portable between any environment
    • Allows encryption to work with load balancing between any environment
  • Rob Watkins 369 posts 701 karma points
    Jun 10, 2014 @ 12:36
    Rob Watkins
    3

    Just wanted to add something; I have been reading through these threads trying to implement best practice on new Umbraco sites.

    I was reading the code for the membership provider wondering how easy it would be to implement a custom BCrypt provider when I discovered the new security stuff and realised I'd no long have to; probably should be reading the blogs more!

    I was quite surprised to discover a completely fresh Umbraco install uses the legacy encoding by default - I can see why you did this for backwards compatibility, but for a brand new install? Seems odd.

    Would it be possible to make it a clear install choice, with prominent help / warnings? I personally think it should be made quite hard to deploy a latest Umbraco version that doesn't have the latest security features.

    Anyway, my situation is that of an installed but still in development, limited number of backoffice users install that I wanted to upgrade security for. Here is how I did it, as there doesn't seem to be a clear instruction yet:

    1. Log in to the back office as your administrator user
    2. Open the web.config and alter the UsersMembershipProvider: (the algorithm is of course optional but I like to know what it is at a glance):

      <add name="UsersMembershipProvider" type="umbraco.providers.UsersMembershipProvider" enablePasswordRetrieval="false" enablePasswordReset="false" requiresQuestionAndAnswer="false" useLegacyEncoding="false" passwordFormat="Hashed" hashAlgorithmType="HMACSHA256" />

    3. Go back to the back office and F5-refresh the page to take note of the changes.

    4. Change your password (if you are looking at the umbracoUsers table you will see the format change completely)
    5. Log out and in again.

    You can now reset any other users passwords manually.

    If the system logs you out for any reason between (2) and (3) you won't be able to log in, but you can just change the web.config back and try again.

    This was a process I just came up with that worked. It may not be the best way.

  • Geofrey 40 posts 161 karma points
    Feb 08, 2018 @ 09:48
    Geofrey
    0

    I have problem with loging to umbraco back office here is my post regarding the issue.

    https://our.umbraco.org/forum/using-umbraco-and-getting-started/90469-i-cant-login-to-umbraco-back-office#comment-285613
    

    can you guys help?

Please Sign in or register to post replies

Write your reply to:

Draft