Redact user input in selected logs. (#14748)
Some checks failed
CI / test-ubuntu-latest (push) Has been cancelled
CI / test-sanitizer-address (push) Has been cancelled
CI / build-debian-old (push) Has been cancelled
CI / build-macos-latest (push) Has been cancelled
CI / build-32bit (push) Has been cancelled
CI / build-libc-malloc (push) Has been cancelled
CI / build-centos-jemalloc (push) Has been cancelled
CI / build-old-chain-jemalloc (push) Has been cancelled
Codecov / code-coverage (push) Has been cancelled
External Server Tests / test-external-standalone (push) Has been cancelled
External Server Tests / test-external-cluster (push) Has been cancelled
External Server Tests / test-external-nodebug (push) Has been cancelled
Spellcheck / Spellcheck (push) Has been cancelled

This PR continues the work #14645, to further ensure sensitive user
data is not exposed in logs when hide_user_data_from_log is enabled.

- Redact empty key notices during RDB load.
- Redact key names in eviction/expiration debug logs.
- Block DEBUG SCRIPT output and suppress raw string dump in crash object
debug when redaction is enabled.
- Redact malformed MODULE LOAD argument snippets and unresolved module
configuration logs.
- Redact empty key notices during RDB load.
- Redact key names during Lua globals allow‑list warnings.
This commit is contained in:
RoyBenMoshe 2026-01-29 17:42:19 +02:00 committed by GitHub
parent 0024d5dfde
commit bf6287d087
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 12 additions and 8 deletions

View file

@ -2701,7 +2701,7 @@ static void deleteKeyAndPropagate(redisDb *db, robj *keyobj, int notify_type, lo
keyobj = createStringObject(keyobj->ptr, sdslen(keyobj->ptr));
}
serverLog(LL_DEBUG,"key %s %s: deleting it", (char*)keyobj->ptr, notify_type == NOTIFY_EXPIRED ? "expired" : "evicted");
serverLog(LL_DEBUG,"key %s %s: deleting it", redactLogCstr((char*)keyobj->ptr), notify_type == NOTIFY_EXPIRED ? "expired" : "evicted");
/* We compute the amount of memory freed by db*Delete() alone.
* It is possible that actually the memory needed to propagate

View file

@ -1098,6 +1098,10 @@ NULL
server.dict_resizing = atoi(c->argv[2]->ptr);
addReply(c, shared.ok);
} else if (!strcasecmp(c->argv[1]->ptr,"script") && c->argc == 3) {
if (server.hide_user_data_from_log) {
addReplyError(c, "DEBUG SCRIPT is disabled when hide-user-data-from-log is enabled");
return;
}
if (!strcasecmp(c->argv[2]->ptr,"list")) {
dictIterator di;
dictEntry *de;
@ -1268,7 +1272,7 @@ void serverLogObjectDebugInfo(const robj *o) {
* random memory portion to be "leaked" into the logfile. */
if (o->type == OBJ_STRING && sdsEncodedObject(o)) {
serverLog(LL_WARNING,"Object raw string len: %zu", sdslen(o->ptr));
if (sdslen(o->ptr) < 4096) {
if (!server.hide_user_data_from_log && sdslen(o->ptr) < 4096) {
sds repr = sdscatrepr(sdsempty(),o->ptr,sdslen(o->ptr));
serverLog(LL_WARNING,"Object raw string content: %s", repr);
sdsfree(repr);
@ -2250,7 +2254,7 @@ void logCurrentClient(client *cc, const char *title) {
robj *key = getDecodedObject(cc->argv[1]);
kvobj *kv = dbFind(cc->db, key->ptr);
if (kv) {
serverLog(LL_WARNING,"key '%s' found in DB containing the following object:", (char*)key->ptr);
serverLog(LL_WARNING,"key '%s' found in DB containing the following object:", redactLogCstr((char*)key->ptr));
serverLogObjectDebugInfo(kv);
}
decrRefCount(key);

View file

@ -12976,7 +12976,7 @@ void moduleLoadFromQueue(void) {
dictEntry *de;
dictInitIterator(&di, server.module_configs_queue);
while ((de = dictNext(&di)) != NULL) {
serverLog(LL_WARNING, ">>> '%s %s'", (char *)dictGetKey(de), (char *)dictGetVal(de));
serverLog(LL_WARNING, ">>> '%s %s'", redactLogCstr((char *)dictGetKey(de)), redactLogCstr((char *)dictGetVal(de)));
}
dictResetIterator(&di);
serverLog(LL_WARNING, "Module Configuration detected without loadmodule directive or no ApplyConfig call: aborting");
@ -13122,7 +13122,7 @@ int parseLoadexArguments(RedisModuleString ***module_argv, int *module_argc) {
}
break;
} else {
serverLog(LL_NOTICE, "Syntax Error from arguments to loadex around %s.", arg_val);
serverLog(LL_NOTICE, "Syntax Error from arguments to loadex around %s.", redactLogCstr(arg_val));
return REDISMODULE_ERR;
}
}
@ -13647,7 +13647,7 @@ int loadModuleConfigs(RedisModule *module) {
/* If found in the queue, set the value. Otherwise, set the default value. */
if (de) {
if (!performModuleConfigSetFromName(dictGetKey(de), dictGetVal(de), &err)) {
serverLog(LL_WARNING, "Issue during loading of configuration %s : %s", (sds) dictGetKey(de), err);
serverLog(LL_WARNING, "Issue during loading of configuration %s : %s", redactLogCstr((char *)dictGetKey(de)), err);
dictFreeUnlinkedEntry(server.module_configs_queue, de);
dictEmpty(server.module_configs_queue, NULL);
return REDISMODULE_ERR;

View file

@ -3932,7 +3932,7 @@ int rdbLoadRioWithLoadingCtx(rio *rdb, int rdbflags, rdbSaveInfo *rsi, rdbLoadin
* continue loading. */
if (error == RDB_LOAD_ERR_EMPTY_KEY) {
if(empty_keys_skipped++ < 10)
serverLog(LL_NOTICE, "rdbLoadObject skipping empty key: %s", key);
serverLog(LL_NOTICE, "rdbLoadObject skipping empty key: %s", redactLogCstr(key));
sdsfree(key);
} else {
sdsfree(key);

View file

@ -1331,7 +1331,7 @@ static int luaNewIndexAllowList(lua_State *lua) {
}
}
if (!*c && !deprecated) {
serverLog(LL_WARNING, "A key '%s' was added to Lua globals which is not on the globals allow list nor listed on the deny list.", variable_name);
serverLog(LL_WARNING, "A key '%s' was added to Lua globals which is not on the globals allow list nor listed on the deny list.", redactLogCstr(variable_name));
}
} else {
lua_rawset(lua, -3);