summaryrefslogtreecommitdiff
path: root/src/sort.c
diff options
context:
space:
mode:
authorranshid <88133677+ranshid@users.noreply.github.com>2022-03-15 17:14:53 +0200
committerGitHub <noreply@github.com>2022-03-15 17:14:53 +0200
commit1078e30c5ff0e13e18192faada8efe3e97299db3 (patch)
tree88ec59d61f23fdeee08fbfb084dec9623cdbcbd0 /src/sort.c
parentcf6dcb7bf1f65dd52d97e134223eb6661aa69f64 (diff)
downloadredis-1078e30c5ff0e13e18192faada8efe3e97299db3.tar.gz
make sort/ro commands validate external keys access patterns (#10106) (#10340)
Currently the sort and sort_ro can access external keys via `GET` and `BY` in order to make sure the user cannot violate the authorization ACL rules, the decision is to reject external keys access patterns unless ACL allows SORT full access to all keys. I.e. for backwards compatibility, SORT with GET/BY keeps working, but if ACL has restrictions to certain keys, these features get permission denied. ### Implemented solution We have discussed several potential solutions and decided to only allow the GET and BY arguments when the user has all key permissions with the SORT command. The reasons being that SORT with GET or BY is problematic anyway, for instance it is not supported in cluster mode since it doesn't declare keys, and we're not sure the combination of that feature with ACL key restriction is really required. **HOWEVER** If in the fullness of time we will identify a real need for fine grain access support for SORT, we would implement the complete solution which is the alternative described below. ### Alternative (Completion solution): Check sort ACL rules after executing it and before committing output (either via store or to COB). it would require making several changes to the sort command itself. and would potentially cause performance degradation since we will have to collect all the get keys instead of just applying them to a temp array and then scan the access keys against the ACL selectors. This solution can include an optimization to avoid the overheads of collecting the key names, in case the ACL rules grant SORT full key-access, or if the ACL key pattern literal matches the one used in GET/BY. It would also mean that authorization would be O(nlogn) since we will have to complete most of the command execution before we can perform verification Co-authored-by: Madelyn Olson <madelyneolson@gmail.com> Co-authored-by: Oran Agra <oran@redislabs.com>
Diffstat (limited to 'src/sort.c')
-rw-r--r--src/sort.c18
1 files changed, 16 insertions, 2 deletions
diff --git a/src/sort.c b/src/sort.c
index 153d6ba79..62e7ad701 100644
--- a/src/sort.c
+++ b/src/sort.c
@@ -197,13 +197,15 @@ void sortCommandGeneric(client *c, int readonly) {
int syntax_error = 0;
robj *sortval, *sortby = NULL, *storekey = NULL;
redisSortObject *vector; /* Resulting vector to sort */
-
+ int user_has_full_key_access = 0; /* ACL - used in order to verify 'get' and 'by' options can be used */
/* Create a list of operations to perform for every sorted element.
* Operations can be GET */
operations = listCreate();
listSetFreeMethod(operations,zfree);
j = 2; /* options start at argv[2] */
+ user_has_full_key_access = ACLUserCheckCmdWithUnrestrictedKeyAccess(c->user, c->cmd, c->argv, c->argc, CMD_KEY_ACCESS);
+
/* The SORT command has an SQL-alike syntax, parse it */
while(j < c->argc) {
int leftargs = c->argc-j-1;
@@ -233,13 +235,20 @@ void sortCommandGeneric(client *c, int readonly) {
if (strchr(c->argv[j+1]->ptr,'*') == NULL) {
dontsort = 1;
} else {
- /* If BY is specified with a real patter, we can't accept
+ /* If BY is specified with a real pattern, we can't accept
* it in cluster mode. */
if (server.cluster_enabled) {
addReplyError(c,"BY option of SORT denied in Cluster mode.");
syntax_error++;
break;
}
+ /* If BY is specified with a real pattern, we can't accept
+ * it if no full ACL key access is applied for this command. */
+ if (!user_has_full_key_access) {
+ addReplyError(c,"BY option of SORT denied due to insufficient ACL permissions.");
+ syntax_error++;
+ break;
+ }
}
j++;
} else if (!strcasecmp(c->argv[j]->ptr,"get") && leftargs >= 1) {
@@ -248,6 +257,11 @@ void sortCommandGeneric(client *c, int readonly) {
syntax_error++;
break;
}
+ if (!user_has_full_key_access) {
+ addReplyError(c,"GET option of SORT denied due to insufficient ACL permissions.");
+ syntax_error++;
+ break;
+ }
listAddNodeTail(operations,createSortOperation(
SORT_OP_GET,c->argv[j+1]));
getop++;