Acme.sh: Security Issue - Generated private key files are world readable

Created on 21 Aug 2020  路  9Comments  路  Source: acmesh-official/acme.sh

Latest version of acme.sh - 2.8.7

Current Behaviour

  • _createkey() function generated *.key files are world readable with -rw-r--r-- (0644) permissions.
  • _installcert() function writes new keys into a world-readable *.key file prior to changing its permissions to -rw------- (0600).
  • _create_account_key() function writes new keys into a world-readable *.key file prior to changing its permissions to -rw------- (0600).

Security Issues
This exposes the private keys of certificates to all processes and all users of the system.
New CA account keys are also briefly exposed when created.
This issue may warrant a CVE report.

Expected Behaviour
All three functions should behave as follows when writing/copying key files:

  • function creates new key files with -rw------- (0600) permissions prior to writing/copying keys into them.
  • function does not change permissions of already existing key files when updating the keys.
  • function outputs and logs a coloured Warning message if the existing key file permissions are world readable:

    • Warning that the private key file is world readable by anyone on this system,

    • Recommending that user changes file permissions to -rw------- (0600), and

    • Recommending that user runs acme.sh commands (depends on function) to force generation of new keys.

The above behaviour should be applied to creation of the following key types:

  • RSA keys generated by _createkey()
  • ECDSA keys generated by _createkey()
  • keys installed by _installcert()
  • keys backed up by _installcert()
  • keys generated by _create_account_key()

All 9 comments

Additional points for the Warning message:

  • Recommending that user replaces certificate with compromised keys on all server applications/hosts, and
  • Recommending that user revokes the old certificate once it has been replaced.

While in many situations only sysadmin staff would have access to a system with world-readable key files, this issue becomes really serious on multi-user systems (e.g. universities, development environments) or on provider/client systems (e.g. PaaS cloud).

It becomes especially aggravated for wildcard certificates, or certificates that are re-used on multiple server applications, or multiple domains/hostnames.

The exact phrasing of the warning message may need some thoughts, but it should really cover the five points above.

I don't think that is an issue necessarily, because everything is done in LE_CONFIG_DIR, which is 0700 and thus not accessible, and when certs are installed wherever they need to go with --install-cert, the key's permissions are changed to 0600.

However, at least some of the deploy_hooks in their default configuration will put the files in unsafe places. I haven't checked them all, but unless I'm totally misreading the code, at least

  • the ssh.sh hook will, even if the user has set safe permissions for the target dir, by default copy a world-readable key file to a world-readable backup dir. This is only a backup, so there is only a brief vulnerability window, but still.
  • the vsftpd.sh & exim4.sh will copy world-readable keys to a world-readable dir
  • some others, like mailcow.sh and strongswan.sh might or might not be saved by the dir permissions the targeted programs set for their config files (strongswan.sh is, strongswan sets its key dirs to 0700. No idea about mailcow, I never used it).

Leaving aside the question of whether it would make sense to create the acme.sh-internal private key files with 0600 in the first place, it's probably a good idea for hooks to use installcert() for copying & backup of certs if possible.

The generated key files are left inside DOMAIN_PATH, not LE_CONFIG_HOME, and it is definitely 0755.
So there's no such thing as "acme.sh-internal private key files". They are all world-readable, including all directories forming their path.

Even if the directories were private, it is still good house keeping to carefully manage the keys.
This is supposed to be acme.sh main purpose: security and cryptographic key management.
It is the primary functionality, and should be taken seriously.

Thanks for identifying more scripts that pass the keys around.

everything is done in LE_CONFIG_DIR, which is 0700 and thus not accessible

Nope. acme.sh does not seem to verify if the permissions are 0700 in case the directory already exists or is a symlink, so it is _not_ guaranteed that $LE_CONFIG_DIR is not accessible.

And generally: private keys need to be 0600 by default, independent where they are to avoid disclosure due to permission mistakes elsewhere. This is not really debatable but common sense.

Look at OpenSSH how pedantic they care about the private key permissions. Take that as a pattern and you're fine.

Nope. acme.sh does not seem to verify if the permissions are 0700 in case the directory already exists or is a symlink, so it is not guaranteed that $LE_CONFIG_DIR is not accessible.

If the dir doesn't exist, acme.sh will create it as 700 permissions. If we do, we do it securely.

If the dir was already created by the administrator, we don't change the permissions, It's the administrator's responsibility to keep the system safe. The administrator knows more/better his system than acme.sh. If we change the permissions to 700, it may make his system down.

This is supposed to be acme.sh main purpose: security and cryptographic key management.

Not really. acme.sh is to request/issue certs/keys from a ACME CA. We never want to Manage the keys on the system. We do our best to keep the keys secret. but if the administrator sets the permission other than 700, we will respect it.

We respect the administrator more than ourselves.

We never want to give the administrator surprises to make his system down.

I explained thousands of times.

Hi @Neilpang

The issue is not about changing or managing permissions of existing files or directories.
I agree, existing file/directory permissions should not be touched.
The issue is about what permissions new key files are created with.

Everyone's default expectation is for any software that creates keys to save them into files with secure permissions, not with world-readable permissions.
I agree with @xtaran - it is not really debatable but common sense.

Sometimes things need to be done quick and people don't have time to read through code to sanity check things, and have to trust the software that they are using to do the right common sense thing.

Sometimes the administrator who is not yet familiar with the software just trusts in what is presented to them.

Case in point - Gentoo distribution acme.sh installer:

  1. Creates world-readable /etc/acme-sh with 755 permissions,
  2. Sets the following system-wide bash alias: alias acme.sh="/usr/bin/acme.sh --config-home '/etc/acme-sh/'"
  3. Sets the following system-wide environment variables:
LE_WORKING_DIR="/etc/acme-sh/"
LE_CONFIG_HOME="/etc/acme-sh/"

This is done on installation, before anyone starts using acme.sh.

When used, the resulting --install-cert key file permissions look sane - so everyone is happy.

I'm pretty sure neither the distribution package maintainer, nor administrator expect that acme.sh creates and stores world-readable key files in its working directories, as they are not intimately familiar with internal workings of acme.sh.

No.
This should be done first and foremost on the key files themselves when they are created or copied.

Don't assume that your script created the folders, or that they have been created with right permissions.
Technically if permissions on the key files are right - directory permissions are not that important (as long as they are not world-writable).

In the Gentoo example above - I've been using acme.sh for almost a year before I spotted this problem.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

extensionsapp picture extensionsapp  路  3Comments

FernandoMiguel picture FernandoMiguel  路  5Comments

hxx-fetch picture hxx-fetch  路  4Comments

MarcusWolschon picture MarcusWolschon  路  3Comments

axiades picture axiades  路  3Comments