>Synopsis:      login_yubikey(8) leaks sensitive data to syslog
>Category:      Security
>Environment:
        System      : OpenBSD 7.6
        Details     : OpenBSD 7.6-current (CUSTOM) #4: Sat Dec 14 01:13:27 GMT 
2024
                         lloyd@bsdtst01:/sys/arch/amd64/compile/CUSTOM

        Architecture: OpenBSD.amd64
        Machine     : amd64
>Description:

login_yubikey(8) leaks the Yubikey OTP Private ID (aka 'uid') and other details
including the OTP counter value to the syslog.

The Private ID (uid) is encrypted with some other data including the counter
value and a nonce using the symmetric AES key to form the OTP.

Background:
https://docs.yubico.com/yesdk/users-manual/application-otp/yubico-otp.html#private-id

These data are typically chmod 0640 or 0660 root:auth on an OpenBSD system and
should not be written to syslog in the clear. Some of these are posted at log
level LOG_INFO so there is a potential they are being captured in remote syslog
servers. I've provided a proposed patch below, apologies if it's mangled.

Alternatively, consider printing these data only if the -d flag is passed and
then only to stdout.

--- login_yubikey.c.orig        Sat Sep  3 11:01:44 2016
+++ login_yubikey.c     Thu Jan 16 12:24:28 2025
@@ -252,16 +252,11 @@ yubikey_login(const char *username, const char *passwo
                        if (!yubikey_crc_ok_p((uint8_t *)&tok))
                                continue;       /* try another one */
                        crcok++;
-                       syslog(LOG_DEBUG, "user %s: crc %04x ok",
-                           username, tok.crc);
+                       syslog(LOG_DEBUG, "user %s: crc ok", username);

                        if (memcmp(tok.uid, uid, YUBIKEY_UID_SIZE)) {
-                               char h[13];
-
-                               yubikey_hex_encode(h, (const char *)tok.uid,
-                                   YUBIKEY_UID_SIZE);
-                               syslog(LOG_DEBUG, "user %s: uid %s != %s",
-                                   username, h, hexuid);
+                               syslog(LOG_DEBUG, "user %s: uid doesn't match",
+                                   username);
                                continue;       /* try another one */
                        }
                        break; /* uid matches */
@@ -282,18 +277,16 @@ yubikey_login(const char *username, const char *passwo

        explicit_bzero(key, sizeof(key));

-       syslog(LOG_INFO, "user %s uid %s: %d matching keymaps (%d checked), "
-           "%d crc ok", username, hexuid, mapok, i, crcok);
+       syslog(LOG_INFO, "user %s uid: %d matching keymaps (%d checked), "
+           "%d crc ok", username, mapok, i, crcok);

        ctr = ((u_int32_t)yubikey_counter(tok.ctr) << 8) | tok.use;
        if (ctr <= last_ctr) {
-               syslog(LOG_INFO, "user %s: counter %u.%u <= %u.%u "
-                   "(REPLAY ATTACK!)", username, ctr / 256, ctr % 256,
-                   last_ctr / 256, last_ctr % 256);
+               syslog(LOG_INFO, "user %s: counter <= last (REPLAY ATTACK!)",
+                   username);
                return (AUTH_FAILED);
        }
-       syslog(LOG_INFO, "user %s: counter %u.%u > %u.%u",
-           username, ctr / 256, ctr % 256, last_ctr / 256, last_ctr % 256);
+       syslog(LOG_INFO, "user %s: counter > last [OK]", username);
        umask(S_IRWXO);
        if ((f = fopen(fn, "w")) == NULL) {
                syslog(LOG_ERR, "user %s: fopen: %s: %m", username, fn);

Reply via email to