Commit Diff


commit - 84735034ed87be9473fe2fadbe6ad11a6b4e13bc
commit + 953390185b209ae9115228e09215cac61c008711
blob - ad307549dfe244aead8140664d85dc8694246a09
blob + 1981c1422ee6ed11f45624514978c8a92fb8204e
--- FICS/gamedb.c
+++ FICS/gamedb.c
@@ -1626,11 +1626,21 @@ OldestHistGame(char *login)
 	char		 pFile[MAX_FILENAME_SIZE] = { '\0' };
 	long int	 when;
 
-	/* Validate login to prevent path traversal */
-	if (strstr(login, "..") || strchr(login, '/') || strchr(login, '\\')) {
+	/* Validate login to prevent path traversal and restrict to safe characters */
+	if (login == NULL || login[0] == '\0' ||
+	    strstr(login, "..") || strchr(login, '/') || strchr(login, '\\')) {
 		warnx("%s: invalid login value: '%s'", __func__, login);
 		return 0L;
 	}
+	for (const char *p = login; *p; ++p) {
+		if (!((*p >= 'a' && *p <= 'z') ||
+		      (*p >= 'A' && *p <= 'Z') ||
+		      (*p >= '0' && *p <= '9') ||
+		      *p == '_')) {
+			warnx("%s: invalid character in login: '%s'", __func__, login);
+			return 0L;
+		}
+	}
 
 	msnprintf(pFile, sizeof pFile, "%s/player_data/%c/%s.%s", stats_dir,
 	    login[0], login, STATS_GAMES);