?
avatar jzlcdh
jzlcdh
18 Aug 2014

Steps to reproduce the issue

Backup (e.g. using Akeeba backup)
Transfer to new site (e.g. using Akeeba Kickstart)
Attempt to log in to above user

Expected result

Successful login to backend on new site.

Actual result

Unable to login and receive message: "An error has occurred. Must match character set."

System information (as much as possible)

PHP 5.4

Additional comments

Bug maybe also affects one or more of the documents:
http://docs.joomla.org/Backup_Basics_for_a_Joomla!_Web_Site#More_Backup_Documentation
http://docs.joomla.org/Security_Checklist/Site_Administration
http://docs.joomla.org/What_are_the_best_practices_for_site_backups%3F
as one doc needs to explain if all the admin user-ids were set to 2FA how would we recover in case of a complete disaster at the live server?

Was bugged on old tracker as #34075 and the following comment was written by Nicholas Dionysopoulosscreen shot 2014-08-18 at 01 18 18:
The problem you have happens because the 2FA configuration is encrypted with the site's $secret key, as defined in configuration.php. When transferring a site to a new server the $secret value must be changed for security reasons. Unfortunately this also renders the 2FA inoperable as its configuration can no longer be decrypted.

If you are locked out of your site you can rename the folder plugins/twofactorauth to twofactorauth.BAK and log in to your site's back-end. Then disable all plugins under the "twofactorauth" group. Finally, rename the plugins/twofactorauth.BAK folder of your site back to twofactorauth.

If you want to re-enable two factor authentication you will have to clear the otpKey and otep fields of all records of the #__users table, then publish the twofactorauth plugins again.

As I had said when I wrote the 2FA feature: encrypting the 2FA configuration with the $secret value is a really bad idea. It only leads to problems (can't log in after doing a proper site transfer) or security issues (2FA having to be disabled, users ending up not changing $secret when moving sites which can potentially expose them to security threats). It would be best if we didn't encrypt the 2FA setting OR encrypting them with a key that's configured in the options of the Users Manager. Maybe the PLT wants to discuss this? I can write the patch for either solution.

avatar jzlcdh jzlcdh - open - 18 Aug 2014
avatar jzlcdh
jzlcdh - comment - 18 Aug 2014

@nikosdion
You may blame the J!Tracker Application at http://issues.joomla.org/ for transmitting this comment.

avatar nikosdion
nikosdion - comment - 18 Aug 2014

Thinking about it more thoroughly, I can see why we chose to use encryption on the 2FA config. If someone exploits an SQL injection or similar attack to dump the contents of the #__users table we don't want to expose the 2FA configuration information. So, if someone has access to the db the encryption key to this information shouldn't be there.

However, the $secret was never intended to be a permanent encryption key. When you clone a site you are supposed to change its value. Maybe we need a different Global Configuration value, let's say $encryptionKey, holding a value which is supposed to be immutable throughout the lifetime of the site and all of its clones. Otherwise we need to provide a tool to website owners to mass decrypt the 2FA configuration with the old $secret and re-encrypt it with the new value.

avatar jzlcdh
jzlcdh - comment - 18 Aug 2014

I don't know any other CMS myself but presumably there are other CMS with 2FA which face a similar problem - I wonder how they handle it?

avatar Bakual
Bakual - comment - 18 Aug 2014

I don't think you can change the secret within the CMS itself. So it's something you have to do either with extern tools (like Akeeba Backup) or by manually editing the configuration.php. Or am I wrong here?

If so I wonder if we need to take care in code of every change someone could make. Personally I doubt it. I don't see it really as a bug.

Of course something can be added to the documentation which explains how to recover the site. Also if there is a doc page which states to change the $secret while moving a site, one could add a warning there as well so people disable 2FA prior to the move.

If there is an easy way of solving that, then I'm sure a PR is welcome. But if it means a complex change then I'm not that sure.

Maybe we need a different Global Configuration value, let's say $encryptionKey, holding a value which is supposed to be immutable throughout the lifetime of the site and all of its clones.

And then someone changes that and the same thing happens again? Not sure if that is the best solution.

avatar nikosdion
nikosdion - comment - 18 Aug 2014

Look, when I proposed 2FA I was against the encryption of its settings. I was told to implement it anyway so here we are now, at a position that whenever $secret changes 2FA is broken for all users, not just the Super User. The $secret is recommended to change when you transfer your site and it may also be required to change after a 3PD extension screws up and somehow ends up leaking it. You might be surprised at who's still doing crap like that, but I digress...

I can of course make sure that when my software changes $secret it will encrypt again the 2FA settings. However this makes my software the only way to transfer / clone a site correctly and I obviously don't like the sound of that. Since I was the person who proposed 2FA –even though I also was the one NOT wanting the settings encryption which causes this issue– I am pretty sure that the usual suspects will accuse me that I put this feature in Joomla! to make more money for myself. That's why I HAD to propose a solution to this problem. If the PLT thinks that there is no problem, cool, I will bookmark this issue for future reference.

avatar beat
beat - comment - 18 Aug 2014

@nikosdion Actually, if I understand correctly, the problem is due to Akeeba-backup not restoring $secret same as on original backup-copy when restoring a backed-up site ?

avatar brianteeman
brianteeman - comment - 18 Aug 2014

the $secret should always be unique for every site and its not something
enforced by the core which means that some extensions have used it as a
unique security key when it isnt.

On 18 August 2014 22:34, beat notifications@github.com wrote:

@nikosdion https://github.com/nikosdion Actually, if I understand
correctly, the problem is due to Akeeba-backup not restoring $secret same
as on original backup-copy when restoring a backed-up site ?


Reply to this email directly or view it on GitHub
#4126 (comment).

Brian Teeman
Co-founder Joomla! and OpenSourceMatters Inc.
http://brian.teeman.net/

avatar beat
beat - comment - 18 Aug 2014

@brianteeman But that means that if a site is backed-up and then restored by any backup-tool, then, by design, $secret should be restored as is too ?

avatar mbabker
mbabker - comment - 18 Aug 2014

No, it shouldn't. If the $secret var were intended to be reused as is we could just hard code its value at install time instead of dynamically generate a value. Nic's tools handle this variable correctly in resetting the value on a backup/restore action to retain the uniqueness. It comes at the expense of anything relying on it as part of an encryption mechanism needing to be reset for the new $secret value or by admins needing to pull their old value in.

avatar jzlcdh
jzlcdh - comment - 19 Aug 2014

@Bakual Disabling 2FA prior to a move is all very well but a disaster recovery situation also needs to be taken into account. In that case one might not have the luxury of being able to take a new backup, or accessing anything at all at the previous live site, but might be relying on a previous scheduled offsite backup. Should the immediate advice until a long term solution is found be that on live sites at least one admin user should not use 2FA? In other words that 2FA is still an experimental feature for the moment. Or is there some other way round the DR scenario which could be written in the documentation?

avatar nikosdion
nikosdion - comment - 19 Aug 2014

In a disaster recovery situation you can use the folder renaming trick I proposed:

If you are locked out of your site you can rename the folder plugins/twofactorauth to twofactorauth.BAK and log in to your site's back-end. Then disable all plugins under the "twofactorauth" group. Finally, rename the plugins/twofactorauth.BAK folder of your site back to twofactorauth.

avatar beat
beat - comment - 19 Aug 2014

@jzlcdh Thanks for maintaining documentation, it is an important aspect!

@nikosdion @mbabker Sorry to come back to this important issue that potentially affects the reputation of Joomla:

If a backup does not serve the main purpose of insuring smoothly a disaster recovery situation, then it should not be called "backup" but something else like "cloner" (but not "archive" which should be a faithful reference copy too).

And that is not only my own humble interpretation as a non-native-English-speaker, but it comes from dictionaries definitions (and don't tell me that a secret key is not important data to back up):

http://www.oxforddictionaries.com/definition/english/backup A copy of a file or other item of data made in case the original is lost or damaged: make a backup of any important files.

https://en.wikipedia.org/wiki/Backup : In information technology, a backup, or the process of backing up, refers to the copying and archiving of computer data so it may be used to restored the original after a data loss event.

avatar nikosdion
nikosdion - comment - 19 Aug 2014

@beat When a backup does not maintain SECURITY OF THE SYSTEM above all else, it's bullshit. Maybe you'd like to review your posts in this thread and think about whether you are proposing that my software should screw its users' security over convenience. As Brian and Michael have already explained the $secret MUST NOT be hardcoded. Think before you subtly accuse people of not knowing what they are doing and have been awarded for in the last 8 years. Thanks and goodbye.

PS: Since you are so fond of dictionaries http://www.oxforddictionaries.com/definition/english/security "The state of being free from danger or threat"

https://en.wikipedia.org/wiki/Security "Security is the degree of resistance to, or protection from, harm. It applies to any vulnerable and valuable asset, such as a person, dwelling, community, nation, or organization."

avatar nikosdion
nikosdion - comment - 19 Aug 2014

Oh, and for what it's worth, you CAN override a Super User's login information when restoring a backup. The problem is that the other logins protected by 2FA won't work unless you disable 2FA plugins. Just so that we know what we're talking about.

Moreover, Akeeba Backup (actually: ANGIE) is aware of 2FA and tries to re-encrypt the config if it detects Joomla! 3.2 or later. The only reason Akeeba Backup stopped re-encrypting the 2FA information in Joomla! 3.3 is that the libraries/cms/version/version.php changed defined('_JEXEC') or die; with defined('JPATH_PLATFORM') or die;. If you want to religiously stick to semantics this is a bug because this file is part of the CMS, not the platform, therefore it should be checking for _JEXEC. Since the respository is public you can see that I am speaking the truth. In any case, I have now worked around that issue. I am also considering no longer including this file, instead parsing it manually. This would 100% decouple the restoration script from Joomla!'s files, at last...

avatar brianteeman brianteeman - close - 19 Aug 2014
avatar zero-24 zero-24 - close - 19 Aug 2014
avatar brianteeman
brianteeman - comment - 19 Aug 2014

As the docs have now been updated (massive thanks for that) I am closing this issue

avatar brianteeman brianteeman - change - 19 Aug 2014
Status New Closed
Closed_Date 0000-00-00 00:00:00 2014-08-19 09:06:17
avatar brianteeman brianteeman - close - 19 Aug 2014
avatar beat
beat - comment - 19 Aug 2014

@nikosdion no personal attacks please. I did not attack you personally, and am sorrry if you felt that way as it wasn't my intention. So please refrain from attacking me. Thanks.

Regarding security: Who wouldn't expect that a backup of confidential security-related information doesn't contain the security-related information ?

Anyway, as you worked around the issue in Akeeba Backup, I guess this thread can be closed, and we can peacefully drink our next beer together. :-)

avatar nikosdion
nikosdion - comment - 19 Aug 2014

@beat The $secret key plays an important role in Joomla!. It's used in JApplicationHelper::getHash() and in the session name. When a site gets hacked and you restore* it from a backup you definitely want $secret to be different, or you're as good as hacked all over again. Even if you unhack your site manually you need to change $secret for the same reason.

Moreover when you clone a site you do need $secret to change, otherwise you can have some interesting side effects. I have a high profile Joomla!-related business in mind and the way they abuse $secret. I believe you know who and what I mean. Overall, the only way to ensure end-users' security is changing the $secret upon restoration.

Now, what was the Joomla! docs page about extension development best practices? I can't seem to be able to find it. We need to add a warning there that $secret should not be used as an immutable site identifier or encryption key.

  • Yes, I know you shouldn't do that, but can you really trust panicked end users to take their time reading the documentation on properly unhacking their site? That's a very rhetorical question, the answer is "of course not" :)
avatar zero-24
zero-24 - comment - 19 Aug 2014

@nikosdion

If you want to religiously stick to semantics this is a bug because this file is part of the CMS, not the platform, therefore it should be checking for _JEXEC.

It was changed here: #3729 which standardise the libraries to defined('JPATH_PLATFORM') or die; So the wohle libraries folder use now defined('JPATH_PLATFORM') or die; It has nothing to do that it is a part of the platform or the CMS :smile:

avatar beat
beat - comment - 19 Aug 2014

@nikosdion Thanks for the constructive clarification on the purpose. That should sure go into the wiki somewhere...

Actually, the $secret should not be used by any third-party extension for purposes others than securing actual sessions...in a secure way. And as that requires quite some security knowledge, it should better be translated by: $secret is a Joomla internal private value not for use by extensions. LOL.

Which means that its current use by Joomla to encrypt a joomla config is completely wrong as you stated (and was probably due by misunderstanding of its meaning or lack of documentation thereof), and is a bad example to third-party developers. So should this issue be re-opened to fix that ?

avatar nikosdion
nikosdion - comment - 19 Aug 2014

That was exactly my point when I proposed using a different encryption key for 2FA.

avatar jzlcdh
jzlcdh - comment - 19 Aug 2014

My update of the docs was just to link to this issue so people could see how to work around it. So I don't think it justifies closing the issue.

@nikosdion You said "you CAN override a Super User's login information when restoring a backup". Is that a general statement I could put ın the documentation or specifically for your software?

avatar nikosdion
nikosdion - comment - 19 Aug 2014

It only applies to my software.

avatar jzlcdh
jzlcdh - comment - 19 Aug 2014

So if I add to the docs what was written above "If you are locked out of your site you can rename the folder plugins/twofactorauth to twofactorauth.BAK and log in to your site's back-end. Then disable all plugins under the "twofactorauth" group. Finally, rename the plugins/twofactorauth.BAK folder of your site back to twofactorauth." is that sufficient to close the issue? It is sufficient for me personally but then I do not currently have a high profile, high volume, high security site.

avatar nikosdion
nikosdion - comment - 19 Aug 2014

Yes, that’s sufficient :)

avatar Bakual
Bakual - comment - 19 Aug 2014

@jzlcdh Can you update the doc page with the actual advise given here by Nicholas instead of only linking to it? I think it would make the doc page better.

May it also be helpful to create a doc page which explains the use of the various global configuration parameters? I did a short search and the only pages I found are a help page for 1.5 (http://docs.joomla.org/Help15:Screen.config.15) and the API page for JApplication::getCfg() (http://docs.joomla.org/JApplication/getCfg) which mention the $secret.

That was exactly my point when I proposed using a different encryption key for 2FA.

Would it maybe make sense to store this key somewhere within the 2FA plugin instead of adding another global configuration value which may be changed by the user? Just wondering.
If it's best placed in configuration.php, we would just make sure it's clear why we have two similar keys there. Some documentation about the purpose of those two would be needed then I think.

avatar nikosdion
nikosdion - comment - 19 Aug 2014

@Bakual Let's see the pros and cons of each storage method:

  • In the database (plugin or component configuration). It's as good as unencrypted. If an attacker is able to exploit a vulnerability which allows them to dump database contents they can get both the encrypted #__users data and the encryption key.

  • In configuration.php. It is the most logical place to store it, as long as we have a clear description of what it is and let the user change it (with a big, fat warning that it will probably break their site if they don't know what they are doing). Pretty much what we do with the db password.

  • In a separate file, created at installation time. That's the cleanest method but it raises all sort of questions such as how to include it in the plugins, will this file be writable at installation time, what happens if you install Joomla! manually or through thinks like Fantastico and so on.

So, I guess a new configuration.php value would make more sense. We need to document that $secret is used in session names and must not be used anywhere else, where $whateverWeCallTheNewVariable is used by Joomla! and extensions to reversibly encrypt data such as 2FA configuration (noting that you should never use it to reversibly encrypt passwords).

avatar Bakual
Bakual - comment - 19 Aug 2014

So, I guess a new configuration.php value would make more sense. We need to document that $secret is used in session names and must not be used anywhere else, where $whateverWeCallTheNewVariable is used by Joomla! and extensions to reversibly encrypt data such as 2FA configuration (noting that you should never use it to reversibly encrypt passwords).

I agree with that assessment. Thanks for taking the time to explain it.
One thing I wonder is if it's needed to allow the user to change it in the global configuration. We don't let the user change the $secret, which would be less dangerous. Is there a use case where the user would need to change it?
After all the purpose would be that extensions can trust on it to never change, or not? If it can be changed from the global config, I would rather use the $secret as it is less likely to be changed by the user :smile:

avatar jzlcdh
jzlcdh - comment - 19 Aug 2014

My knowledge is very limited compared to you guys. I'll be on holiday for a week from now but when I get back I'll be happy to do some documentation donkey work under your guidance - most likely I'll be copying and pasting stuff from here into the docs and then asking you to check it is right.

avatar nikosdion
nikosdion - comment - 19 Aug 2014

@Bakual Hm, you're right. I see that in Joomla! 3.3 we don't even allow the user to change the db password from Global Configuration. So, configuration.php, no UI to change it.

avatar brianteeman
brianteeman - comment - 19 Aug 2014

If you make a change and add a new variable to configuration.php that's
going to cause upgrade issues as many people make this file unwritable.
Iirc the last time we added a variable (mail setting?) Some people had to
ensure that they opened and saved global config for the change to be
applied.
On 19 Aug 2014 15:37, "Nicholas K. Dionysopoulos" notifications@github.com
wrote:

@Bakual https://github.com/Bakual Hm, you're right. I see that in
Joomla! 3.3 we don't even allow the user to change the db password from
Global Configuration. So, configuration.php, no UI to change it.


Reply to this email directly or view it on GitHub
#4126 (comment).

avatar Bakual
Bakual - comment - 19 Aug 2014

Good point. Adding a new value to that file could indeed be a funny task.
Maybe the best approach would be to use a postinstall message/action which then tries to create the value or guide the user. And also converts 2FA to use the new value.

avatar brianteeman
brianteeman - comment - 19 Aug 2014

That would fail with automated update services offered by hosts etc

On 19 August 2014 18:09, Thomas Hunziker notifications@github.com wrote:

Good point. Adding a new value to that file could indeed be a funny task.
Maybe the best approach would be to use a postinstall message/action which
then tries to create the value or guide the user. And also converts 2FA to
use the new value.


Reply to this email directly or view it on GitHub
#4126 (comment).

Brian Teeman
Co-founder Joomla! and OpenSourceMatters Inc.
http://brian.teeman.net/

avatar nikosdion
nikosdion - comment - 19 Aug 2014

By definition Brian the files are writable in this use case, otherwise the upgrade can't happen.

avatar brianteeman
brianteeman - comment - 19 Aug 2014

even configuration.php ??? We never touch that file in an upgrde

On 19 August 2014 18:38, Nicholas K. Dionysopoulos <notifications@github.com

wrote:

By definition Brian the files are writable in this use case, otherwise the
upgrade can't happen.


Reply to this email directly or view it on GitHub
#4126 (comment).

Brian Teeman
Co-founder Joomla! and OpenSourceMatters Inc.
http://brian.teeman.net/

avatar nikosdion
nikosdion - comment - 19 Aug 2014

By definition. It will either be owned by the PHP user or the FTP user.

If the site's files are owned by the PHP user so is configuration.php

If the site's files are owned by the FTP user the configuration.php can be owned by anyone - the upgrade script has access to both FTP and PHP users.

avatar brianteeman
brianteeman - comment - 19 Aug 2014

I'm not talking about ownership I'm talking about permissions. Remember
many "security" advisers recommend setting this to be unwritable

On 19 August 2014 19:37, Nicholas K. Dionysopoulos <notifications@github.com

wrote:

By definition. It will either be owned by the PHP user or the FTP user.

If the site's files are owned by the PHP user so is configuration.php

If the site's files are owned by the FTP user the configuration.php can be
owned by anyone - the upgrade script has access to both FTP and PHP users.


Reply to this email directly or view it on GitHub
#4126 (comment).

Brian Teeman
Co-founder Joomla! and OpenSourceMatters Inc.
http://brian.teeman.net/

avatar nikosdion
nikosdion - comment - 19 Aug 2014

Even if the permissions are 0444 the file is still writeable to its owner: you just have to chmod it to 0644 before writing to it. Just a dirty little UNIX secret ;)

avatar brianteeman
brianteeman - comment - 19 Aug 2014

Yes I know thats all you have to do but we currently dont have a way to do
that (and return it to its previous state) iirc - anyway the point is mute
as it wont help with sites updated outside of the joomla updater by other
scripts

On 19 August 2014 19:47, Nicholas K. Dionysopoulos <notifications@github.com

wrote:

Even if the permissions are 0444 the file is still writeable to its owner:
you just have to chmod it to 0644 before writing to it. Just a dirty little
UNIX secret ;)


Reply to this email directly or view it on GitHub
#4126 (comment).

Brian Teeman
Co-founder Joomla! and OpenSourceMatters Inc.
http://brian.teeman.net/

avatar nikosdion
nikosdion - comment - 19 Aug 2014

Brian, you are wrong. Any updater –no matter who wrote it– MUST load administrator/components/com_admin/script.php and run the update() method providing a JInstallerFile object. Otherwise obsolete files won’t be removed, manifest caches won’t be updated, schema updates won’t be applied and generally the updated site would be broken. If you are talking about an updater which doesn’t do that minimum work to ensure the updated site is working then adding one more parameter would be the least of the site owner’s worries. Besides, we can always modify UsersModelUser to fall back to $secret if the new parameter is not already set, therefore not cause a login failure if the new parameter cannot be saved to configuration.php.

avatar brianteeman
brianteeman - comment - 19 Aug 2014

I've seen the updaters :(
On 19 Aug 2014 19:56, "Nicholas K. Dionysopoulos" notifications@github.com
wrote:

Brian, you are wrong. Any updater –no matter who wrote it– MUST load
administrator/components/com_admin/script.php and run the update() method
providing a JInstallerFile object. Otherwise obsolete files won’t be
removed, manifest caches won’t be updated, schema updates won’t be applied
and generally the updated site would be broken. If you are talking about an
updater which doesn’t do that minimum work to ensure the updated site is
working then adding one more parameter would be the least of the site
owner’s worries. Besides, we can always modify UsersModelUser to fall back
to $secret if the new parameter is not already set, therefore not cause a
login failure if the new parameter cannot be saved to configuration.php.


Reply to this email directly or view it on GitHub
#4126 (comment).

avatar nikosdion
nikosdion - comment - 19 Aug 2014

Then we must start naming names and let our users know that updater X, Y and Z is doing it all wrong, if they use it their site WILL break and all they’ll get from J! developers is tea, sympathy and a reminder to not use broken updaters (minus the tea, he he).

avatar jzlcdh
jzlcdh - comment - 26 Aug 2014

As suggested I have updated the doc pages above with the actual advice given here by Nicholas instead of only linking to it.

But sorry I do not have the knowledge or time to create a doc page which explains the use of the various global configuration parameters.

avatar Bakual
Bakual - comment - 26 Aug 2014

@jzlcdh Thanks for your contribution! It's very appreciated.

avatar zero-24 zero-24 - change - 7 Jul 2015
Labels Added: ?
avatar proden123
proden123 - comment - 24 Dec 2016

I'm having the issue where to factor doesn't work after akeeba transfer from local machine to godaddy shared server. I tried the recommended steps of renaming the folder and disabling the plugin. My otpKey and otep values show empty. I renamed the folder and tried to enable TFA, but nothing happens to user when click save. Any thoughts?

avatar Bakual
Bakual - comment - 24 Dec 2016

Please don't post on closed issues, it will not get any traction.
If you have an issue and are sure it's due to core, please open a new one.
If you just looking for some help or guidance, please use forum.joomla.org

avatar zero-24 zero-24 - locked - 25 Dec 16

Add a Comment

Login with GitHub to post a comment