#3035 Issue closed: lib/authtoken-functions.sh seems to leak secrets with 'set -x'

Labels: documentation, fixed / solved / done

jsmeix opened issue at 2023-08-02 12:22:

  • ReaR version ("/usr/sbin/rear -V"):
    current master code

  • Description of the issue (ideally so that others can reproduce it):

Since
https://github.com/rear/rear/pull/2956
there is
lib/authtoken-functions.sh
which seems to leak secrets with 'set -x', cf.
https://github.com/rear/rear/pull/3034#issuecomment-1662077184

For example the function encrypt_base64 contains

ciphertext=$(openssl aes-256-cbc -a -pbkdf2 -pass pass:"$2" <<< "$plaintext" 2>&1); ret=$?

which leaks the password $2 when 'set -x' is set
like

# ( set -x ; \
 password=PASSWORD ; \
 plaintext=plain_text ; \
 ciphertext=$(openssl aes-256-cbc -a -pbkdf2 -pass pass:"$password" <<< "$plaintext" 2>&1) ; \
 ret=$? ; \
 echo $ret ; \
 echo $ciphertext )

+ password=PASSWORD
+ plaintext=plain_text
++ openssl aes-256-cbc -a -pbkdf2 -pass pass:PASSWORD
+ ciphertext=U2FsdGVkX1/cEmESpmJJr0cblyHQ1AvAXvTkI9qArqk=
+ ret=0
+ echo 0
0
+ echo U2FsdGVkX1/cEmESpmJJr0cblyHQ1AvAXvTkI9qArqk=

versus with proper stderr redirection to /dev/null for the openssl command

# ( set -x ; \
 password=PASSWORD ; \
 plaintext=plain_text ; \
 { ciphertext=$( openssl aes-256-cbc -a -pbkdf2 -pass pass:"$password" <<< "$plaintext" 2>&1 ) ; } 2>/dev/null ; \
 ret=$? ; \
 echo $ret ; \
 echo $ciphertext )

+ password=PASSWORD
+ plaintext=plain_text
+ ret=0
+ echo 0
0
+ echo U2FsdGVkX19ou3CqOsY3kQ3LDePzNIVeFVs3IPjcgpw=
U2FsdGVkX19ou3CqOsY3kQ3LDePzNIVeFVs3IPjcgpw=

jsmeix commented at 2023-08-02 12:28:

@kernins
could you have a look here because you implemented
authtoken-functions.sh
via https://github.com/rear/rear/pull/2956

As an example I think the above command should be

{ ciphertext=$( openssl aes-256-cbc -a -pbkdf2 -pass pass:"$2" <<< "$plaintext" 2>&1 ) ; } 2>>/dev/$SECRET_OUTPUT_DEV ; ret=$?

Regarding

{ SECRET COMMAND ; } 2>>/dev/$SECRET_OUTPUT_DEV

see
https://github.com/rear/rear/pull/3006

Currently SECRET_OUTPUT_DEV is only set in usr/sbin/rear
so when ReaR system startup scripts in skel/default/etc/scripts
call functions in lib/authtoken-functions.sh
we must set SECRET_OUTPUT_DEV also for ReaR system startup scripts.

In particular encrypt_base64() is called in
skel/default/etc/scripts/unlock-opal-disks

So probably it is better - at least for now -
to use hardcoded /dev/null to be fail-safe like

{ ciphertext=$( openssl aes-256-cbc -a -pbkdf2 -pass pass:"$2" <<< "$plaintext" 2>&1 ) ; } 2>/dev/null ; ret=$?

jsmeix commented at 2023-08-02 12:57:

Regarding 'set -x' for ReaR system startup scripts:

'set -x' is set for the ReaR system startup
scripts in /etc/scripts/system-setup.d/*.sh
by the initial startup script /etc/scripts/system-setup
when "debug" is a kernel command line parameter
which can be specified by the user when he boots
the ReaR recovery system.

I don't know how scripts like
/etc/scripts/unlock-opal-disks
are called.
I.e. I don't know if 'set -x' can be set
for /etc/scripts/unlock-opal-disks

jsmeix commented at 2023-08-02 13:06:

According to

# for f in $( grep '^function ' usr/share/rear/lib/authtoken-functions.sh | cut -d ' ' -f2 | cut -d '(' -f1 ) ; do echo $f found in ; find usr/sbin/rear usr/share/rear -type f | xargs grep -l $f ; echo ; done

authtkn_load found in
usr/share/rear/skel/default/etc/scripts/unlock-opal-disks
usr/share/rear/lib/authtoken-functions.sh

authtkn_store found in
usr/share/rear/skel/default/etc/scripts/unlock-opal-disks
usr/share/rear/lib/authtoken-functions.sh

authtkn_wipe found in
usr/share/rear/skel/default/etc/scripts/unlock-opal-disks
usr/share/rear/lib/authtoken-functions.sh

token_read found in
usr/share/rear/lib/authtoken-functions.sh

token_write found in
usr/share/rear/lib/authtoken-functions.sh

blkdev_hash found in
usr/share/rear/lib/authtoken-functions.sh

blkdev_read found in
usr/share/rear/lib/authtoken-functions.sh

blkdev_write found in
usr/share/rear/lib/authtoken-functions.sh

blkdev_model found in
usr/share/rear/skel/default/etc/scripts/unlock-opal-disks
usr/share/rear/lib/authtoken-functions.sh

blkdev_wait found in
usr/share/rear/skel/default/etc/scripts/unlock-opal-disks
usr/share/rear/lib/authtoken-functions.sh

encrypt_base64 found in
usr/share/rear/skel/default/etc/scripts/unlock-opal-disks
usr/share/rear/lib/authtoken-functions.sh

decrypt_base64 found in
usr/share/rear/skel/default/etc/scripts/unlock-opal-disks
usr/share/rear/lib/authtoken-functions.sh

garbage_base64 found in
usr/share/rear/lib/authtoken-functions.sh

all functions in lib/authtoken-functions.sh
are only called in
usr/share/rear/skel/default/etc/scripts/unlock-opal-disks

So when 'set -x ' cannot be set for
/etc/scripts/unlock-opal-disks
then it seems all is OK regarding leaking with 'set -x'.

But I did not check possible leaking without 'set -x'.

kernins commented at 2023-08-02 13:42:

Thanks for your finding!
I'll take a closer look at it when the time permits, no ETA unfortunately.

At a first glance, the only real/practical leak case I see theoretically possible is that when attacker already has an access to both token & device it was generated on (if token is TPM-bound) and/or token 2FA password, which would mean he already can decrypt/unlock the drive. Then either set -x leak (if it can be set) or manual token decryption in CLI (if enabled, which shouldn't be the case) can reveal the actual Opal passphrase.

unlock-opal-disks is run only in pre-boot volatile environment, all secret user-input happens only in that pre-boot environment, and the image is immutable (PBA-area is RO on locked drive)

jsmeix commented at 2023-08-03 06:50:

@kernins
thank you for your prompt reply
and for your explanation.

I found another reason why the current sate is OK:

There is no log file for the ReaR system startup scripts.
While the ReaR system startup scripts are running
their stdin/stdout/stderr is the user's terminal
(usually keyboard and screen).

In particular when 'set -x' is set for the ReaR system
startup scripts, the 'set -x' messages appear only
on the user's terminal.

So only the user who runs ReaR may see his own secrets
on his own terminal.

If the user who runs ReaR works from remote
he has to care himself as usual about the security
of his remote connection (e.g. by using an encrypted
remote connection method like 'ssh').

jsmeix commented at 2023-08-03 06:58:

There is one thing left to do for me:

Because @kernins wrote in
https://github.com/rear/rear/pull/2956#discussion_r1134731456

Although authtoken-functions.sh are generic enough
to possibly find some use also in ReaR context over time,
I'd prefer to keep them self-contained and
easily reusable outside of ReaR

As long as the functions in lib/authtoken-functions.sh
are only called in
usr/share/rear/skel/default/etc/scripts/unlock-opal-disks
things are OK according to the reasoning above.

But if the functions in lib/authtoken-functions.sh
would be called in other ReaR scripts,
then those functions would leak secrets with 'set -x'.

So currently the functions in lib/authtoken-functions.sh
are not properly implemented to be called in other ReaR scripts
or even generically in whatever environment outside of ReaR.

Therefore I will add a comment at the beginning of
lib/authtoken-functions.sh
that explains the current state.

jsmeix commented at 2023-08-03 11:28:

With
https://github.com/rear/rear/commit/1f839f776bf4af0812d9acdbf41c425419b5875b
this issue should be reasonably solved (at least for now).

@kernins
again thank you for your prompt reply
that helped me a lot to get this issue solved.


[Export of Github issue for rear/rear.]