>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);