Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Harden root password class #1485

Merged
merged 3 commits into from
Aug 23, 2022
Merged

Harden root password class #1485

merged 3 commits into from
Aug 23, 2022

Conversation

chelnak
Copy link
Contributor

@chelnak chelnak commented Aug 17, 2022

Prior to this PR there was a possibility that malformed strings could be passed in to the resource.
This could lead to unsafe executions on a remote system.

The parameters that are susceptible are install_secret_file.

This PR fixes the above by adding validation to ensure the given values confirm to expectation.

secret_file is validated with a regular expression that ensures the given value is a valid path.

@chelnak chelnak added the bugfix label Aug 17, 2022
@chelnak chelnak self-assigned this Aug 17, 2022
@chelnak chelnak requested a review from a team as a code owner August 17, 2022 15:29
@puppet-community-rangefinder
Copy link

mysql::db is a type

Breaking changes to this file WILL impact these 67 modules (exact match):
Breaking changes to this file MAY impact these 16 modules (near match):

mysql::server::root_password is a class

that may have no external impact to Forge modules.

This module is declared in 140 of 579 indexed public Puppetfiles.


These results were generated with Rangefinder, a tool that helps predict the downstream impact of breaking changes to elements used in Puppet modules. You can run this on the command line to get a full report.

Exact matches are those that we can positively identify via namespace and the declaring modules' metadata. Non-namespaced items, such as Puppet 3.x functions, will always be reported as near matches only.

@chelnak chelnak force-pushed the maint-harden_root_password_class branch 3 times, most recently from b0e1f67 to d9f03e6 Compare August 17, 2022 15:32
@chelnak
Copy link
Contributor Author

chelnak commented Aug 17, 2022

ping @puppetlabs/security

@chelnak chelnak requested a review from a team August 17, 2022 16:09
@chelnak chelnak force-pushed the maint-harden_root_password_class branch from 0c8be00 to b60b76c Compare August 17, 2022 16:20
@chelnak chelnak requested a review from binford2k August 17, 2022 16:20
@chelnak chelnak force-pushed the maint-harden_root_password_class branch from b60b76c to 1a0fe05 Compare August 17, 2022 21:14
@chelnak
Copy link
Contributor Author

chelnak commented Aug 17, 2022

The test failures in this PR are present on main and part of another investigation.

"mysqladmin -u root --password=\$(grep -o '[^ ]\\+\$' ${secret_file}) password ''",
"rm -f ${secret_file}",
"mysqladmin -u root --password=\$(grep -o '[^ ]\\+\$' /.mysql_secret) password ''",
'rm -f /.mysql_secret',
], ' && ')

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be chained with a ; not &&. If the mysqladmin command fails with the current command chaining it won't delete the .mysql_secret file

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that's desired though. If we remove the file without setting the password, then we've lost it.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤔 we don't want to leave a cleartext file sitting on the hard drive though

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's look at the workflow and fragilities. This is how I understand it, please correct me if I'm wrong.

  1. the mysql install runs and generates a randomized password
  2. this is saved in plaintext on disk. It allows you only the ability to set your own password--you can't use it for normal operations.
  3. the user is expected to specify a new password and delete the temporary password file, which is what this command string is doing.

If step 3 fails, I can only think of a handful of causes:

  1. mysql installation failed or the service didn't start. Manual intervention is required, and the plaintext password may or may not be valid.
  2. race condition -- the install succeeded, but an unknown actor already changed the root password. The plaintext password is invalid, but this should probably trigger an investigation.
  3. the process that generated the install password and file on disk failed. The plaintext password is invalid.

Are there other scenarios?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, assume that something else went wrong with the mysqladmin password change command, in this case the password was not changed or removed, and it's still sitting on the disk, right? The safer option here is to just delete it regardless of success or failure

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd still call that scenario 1 and the proper response imho is to fail and ensure manual intervention. I'm not sure if I care about the password file existing. It could make troubleshooting easier, but I suspect that most users won't bother--they'll either burn the node or remove the installation and try again.

My concern with chaining with ; is that it will make that exec always succeed and so it won't bubble up errors.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how about we do it like this

 mysqladmin -u root --password=\$(grep -o '[^ ]\\+\$' /.mysql_secret) password \
&& (rm -f  /.mysql_secret; exit 0) \
|| (rm -f /.mysql_secret; exit 1)

Now we'll always delete the secret, and we'll have the error if something went wrong?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ha! I looked at the original code again and it wasn't surfacing errors to start with!

@chelnak chelnak force-pushed the maint-harden_root_password_class branch 5 times, most recently from 6e6075e to 0cb1c44 Compare August 22, 2022 09:37
@chelnak chelnak requested a review from a team August 22, 2022 09:54
@chelnak chelnak force-pushed the maint-harden_root_password_class branch 2 times, most recently from 392e0d9 to e00ebec Compare August 23, 2022 08:53
Prior to this commit there was a possibility that malformed
strings could be passed in to the resource. This could lead
to unsafe executions on a remote system.

The parameters that are susceptible are `install_secret_file`.

This commit fixes the above by adding validation to ensure the given
values confirm to expectation.

`secret_file` is validated with a regular expression that ensures the
given value is a valid path.
This commit adds spec tests for the changes made in the previous
commit.
@chelnak chelnak force-pushed the maint-harden_root_password_class branch from e00ebec to 85956f5 Compare August 23, 2022 10:56
LivingInSyn
LivingInSyn previously approved these changes Aug 23, 2022
LivingInSyn
LivingInSyn previously approved these changes Aug 23, 2022
@LukasAud LukasAud merged commit 18813a1 into main Aug 23, 2022
@LukasAud LukasAud deleted the maint-harden_root_password_class branch August 23, 2022 13:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants