From a2e1342655105636fa672ee4d3ee87ca0d46f33a Mon Sep 17 00:00:00 2001 From: iefa m Date: Wed, 4 Nov 2026 15:12:56 +0530 Subject: [PATCH] logsrvd_json_log_cb: don't let client info override server-set keys The JSON event log callback copied every InfoMessage key from the client after format_json() had already written uuid, server_time, submit_time, peeraddr, iolog_path, iolog_offset and reason. A client could send its own peeraddr, uuid or iolog_path and the duplicate key, which most JSON readers resolve to the last value, replaced the value recorded by the server. Skip those keys with a warning. --- logsrvd/logsrvd_local.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/logsrvd/logsrvd_local.c b/logsrvd/logsrvd_local.c index 98a19fec77..d503f5b3d4 100644 --- a/logsrvd/logsrvd_local.c +++ b/logsrvd/logsrvd_local.c @@ -64,6 +64,33 @@ struct logsrvd_info_closure { size_t infolen; }; +/* + * Keys that format_json() writes itself for accept and reject events. + * These must not be overridden by the client. + */ +static const char *reserved_json_keys[] = { + "iolog_offset", + "iolog_path", + "peeraddr", + "reason", + "server_time", + "submit_time", + "uuid", + NULL +}; + +static bool +reserved_json_key(const char *key) +{ + const char **kp; + + for (kp = reserved_json_keys; *kp != NULL; kp++) { + if (strcmp(key, *kp) == 0) + return true; + } + return false; +} + static bool logsrvd_json_log_cb(struct json_container *jsonc, void *v) { @@ -75,6 +102,12 @@ logsrvd_json_log_cb(struct json_container *jsonc, void *v) for (idx = 0; idx < closure->infolen; idx++) { InfoMessage *info = closure->info_msgs[idx]; + if (reserved_json_key(info->key)) { + sudo_warnx(U_("%s: protocol error: reserved key %s"), + "local", info->key); + continue; + } + switch (info->value_case) { case INFO_MESSAGE__VALUE_NUMVAL: json_value.type = JSON_NUMBER;