mirror of
https://github.com/redis/redis.git
synced 2026-04-21 03:01:35 -04:00
Add module API for redacting command arguments (#10425)
Add module API for redacting client commands
This commit is contained in:
19
src/module.c
19
src/module.c
@@ -8611,6 +8611,24 @@ int RM_DeauthenticateAndCloseClient(RedisModuleCtx *ctx, uint64_t client_id) {
|
||||
return REDISMODULE_OK;
|
||||
}
|
||||
|
||||
/* Redact the client command argument specified at the given position. Redacted arguments
|
||||
* are obfuscated in user facing commands such as SLOWLOG or MONITOR, as well as
|
||||
* never being written to server logs. This command may be called multiple times on the
|
||||
* same position.
|
||||
*
|
||||
* Note that the command name, position 0, can not be redacted.
|
||||
*
|
||||
* Returns REDISMODULE_OK if the argument was redacted and REDISMODULE_ERR if there
|
||||
* was an invalid parameter passed in or the position is outside the client
|
||||
* argument range. */
|
||||
int RM_RedactClientCommandArgument(RedisModuleCtx *ctx, int pos) {
|
||||
if (!ctx || !ctx->client || pos <= 0 || ctx->client->argc <= pos) {
|
||||
return REDISMODULE_ERR;
|
||||
}
|
||||
redactClientCommandArgument(ctx->client, pos);
|
||||
return REDISMODULE_OK;
|
||||
}
|
||||
|
||||
/* Return the X.509 client-side certificate used by the client to authenticate
|
||||
* this connection.
|
||||
*
|
||||
@@ -11808,6 +11826,7 @@ void moduleRegisterCoreAPI(void) {
|
||||
REGISTER_API(IsSubEventSupported);
|
||||
REGISTER_API(GetServerVersion);
|
||||
REGISTER_API(GetClientCertificate);
|
||||
REGISTER_API(RedactClientCommandArgument);
|
||||
REGISTER_API(GetCommandKeys);
|
||||
REGISTER_API(GetCommandKeysWithFlags);
|
||||
REGISTER_API(GetCurrentCommandName);
|
||||
|
||||
@@ -3471,7 +3471,11 @@ static void retainOriginalCommandVector(client *c) {
|
||||
* original_argv array. */
|
||||
void redactClientCommandArgument(client *c, int argc) {
|
||||
retainOriginalCommandVector(c);
|
||||
decrRefCount(c->argv[argc]);
|
||||
if (c->original_argv[argc] == shared.redacted) {
|
||||
/* This argument has already been redacted */
|
||||
return;
|
||||
}
|
||||
decrRefCount(c->original_argv[argc]);
|
||||
c->original_argv[argc] = shared.redacted;
|
||||
}
|
||||
|
||||
|
||||
@@ -1143,6 +1143,7 @@ REDISMODULE_API void (*RedisModule_ACLAddLogEntry)(RedisModuleCtx *ctx, RedisMod
|
||||
REDISMODULE_API int (*RedisModule_AuthenticateClientWithACLUser)(RedisModuleCtx *ctx, const char *name, size_t len, RedisModuleUserChangedFunc callback, void *privdata, uint64_t *client_id) REDISMODULE_ATTR;
|
||||
REDISMODULE_API int (*RedisModule_AuthenticateClientWithUser)(RedisModuleCtx *ctx, RedisModuleUser *user, RedisModuleUserChangedFunc callback, void *privdata, uint64_t *client_id) REDISMODULE_ATTR;
|
||||
REDISMODULE_API int (*RedisModule_DeauthenticateAndCloseClient)(RedisModuleCtx *ctx, uint64_t client_id) REDISMODULE_ATTR;
|
||||
REDISMODULE_API int (*RedisModule_RedactClientCommandArgument)(RedisModuleCtx *ctx, int pos) REDISMODULE_ATTR;
|
||||
REDISMODULE_API RedisModuleString * (*RedisModule_GetClientCertificate)(RedisModuleCtx *ctx, uint64_t id) REDISMODULE_ATTR;
|
||||
REDISMODULE_API int *(*RedisModule_GetCommandKeys)(RedisModuleCtx *ctx, RedisModuleString **argv, int argc, int *num_keys) REDISMODULE_ATTR;
|
||||
REDISMODULE_API int *(*RedisModule_GetCommandKeysWithFlags)(RedisModuleCtx *ctx, RedisModuleString **argv, int argc, int *num_keys, int **out_flags) REDISMODULE_ATTR;
|
||||
@@ -1466,6 +1467,7 @@ static int RedisModule_Init(RedisModuleCtx *ctx, const char *name, int ver, int
|
||||
REDISMODULE_GET_API(DeauthenticateAndCloseClient);
|
||||
REDISMODULE_GET_API(AuthenticateClientWithACLUser);
|
||||
REDISMODULE_GET_API(AuthenticateClientWithUser);
|
||||
REDISMODULE_GET_API(RedactClientCommandArgument);
|
||||
REDISMODULE_GET_API(GetClientCertificate);
|
||||
REDISMODULE_GET_API(GetCommandKeys);
|
||||
REDISMODULE_GET_API(GetCommandKeysWithFlags);
|
||||
|
||||
@@ -54,6 +54,16 @@ int Auth_AuthRealUser(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
return RedisModule_ReplyWithLongLong(ctx, (uint64_t) client_id);
|
||||
}
|
||||
|
||||
/* This command redacts every other arguments and returns OK */
|
||||
int Auth_RedactedAPI(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
for(int i = argc - 1; i > 0; i -= 2) {
|
||||
int result = RedisModule_RedactClientCommandArgument(ctx, i);
|
||||
RedisModule_Assert(result == REDISMODULE_OK);
|
||||
}
|
||||
return RedisModule_ReplyWithSimpleString(ctx, "OK");
|
||||
}
|
||||
|
||||
int Auth_ChangeCount(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
REDISMODULE_NOT_USED(argv);
|
||||
REDISMODULE_NOT_USED(argc);
|
||||
@@ -87,6 +97,10 @@ int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
|
||||
Auth_ChangeCount,"",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx,"auth.redact",
|
||||
Auth_RedactedAPI,"",0,0,0) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
|
||||
return REDISMODULE_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -68,6 +68,22 @@ start_server {tags {"modules"}} {
|
||||
assert_equal [r acl whoami] "default"
|
||||
}
|
||||
|
||||
test {modules can redact arguments} {
|
||||
r config set slowlog-log-slower-than 0
|
||||
r slowlog reset
|
||||
r auth.redact 1 2 3 4
|
||||
r auth.redact 1 2 3
|
||||
r config set slowlog-log-slower-than 10000
|
||||
set slowlog_resp [r slowlog get]
|
||||
|
||||
# There will be 3 records, slowlog reset and the
|
||||
# two auth redact calls.
|
||||
assert_equal 3 [llength $slowlog_resp]
|
||||
assert_equal {slowlog reset} [lindex [lindex [r slowlog get] 2] 3]
|
||||
assert_equal {auth.redact 1 (redacted) 3 (redacted)} [lindex [lindex [r slowlog get] 1] 3]
|
||||
assert_equal {auth.redact (redacted) 2 (redacted)} [lindex [lindex [r slowlog get] 0] 3]
|
||||
}
|
||||
|
||||
test "Unload the module - testacl" {
|
||||
assert_equal {OK} [r module unload testacl]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user