Index | Thread | Search

From:
Lloyd <ng2d68@proton.me>
Subject:
patch: stop login_yubikey(8) leaking OTP data to syslog
To:
"tech@openbsd.org" <tech@openbsd.org>
Date:
Wed, 13 Aug 2025 00:00:17 +0000

Download raw body.

Thread
Reposting this patch in case someone wants to consider merging it.

login_yubikey(8) writes out secrets from /var/db/yubikey into syslog.

If you forward syslog messages to a remote server, these could be
leaked or compromised. Note the cleartext values are encrypted with
another key to form the complete OTP. It's not hugely terrible but
writing data from /var/db/yubikey into syslog seems very wrong and
there is no good reason to do it unless you are doing development.

The data is considered private by Yubico. 'uid' is a misnomer as
it's not a username, or UNIX UID, but rather a shared secret.

/var/db/yubikey is normally 0770 root:auth.

Regards
Lloyd

Index: login_yubikey.c
===================================================================
RCS file: /cvs/src/libexec/login_yubikey/login_yubikey.c,v
retrieving revision 1.16
diff -u -p -u -p -r1.16 login_yubikey.c
--- login_yubikey.c	3 Sep 2016 11:01:44 -0000	1.16
+++ login_yubikey.c	19 May 2025 02:05:55 -0000
@@ -252,16 +252,11 @@ yubikey_login(const char *username, cons
 			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, cons

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