Fix "default" and overwritten / reset users will not have pubsub channels permissions by default.#8723
Conversation
When a "default" user is loaded from config file or include acl file with no channels related rules, the user will not have any permissions to any channels. But other users will have default permissions to any channels. When upgraded from 6.0 with config rewrite, this will lead to "default" user channels permissions lost. Additionally this commit rename server.acl_pubusub_default to server.acl_pubsub_default and fix typo in acl tests.
src/acl.c
Outdated
| u = ACLGetUserByName(argv[1],sdslen(argv[1])); | ||
| serverAssert(u != NULL); | ||
| ACLSetUser(u,"reset",-1); | ||
| u->flags = u->flags | server.acl_pubsub_default; |
There was a problem hiding this comment.
@huangzhw do you think maybe it would be better to move this into ACLSetUser("reset")?
the docs say this about "reset":
The user returns to the same state it has immediately after its creation.
There was a problem hiding this comment.
@oranagra Thie will be a bigger step. If we add this in reset, the behavior will not be compatible with 6.2. Although it will conform to the docs. WDYT which is preferred?
Another way this bug affect not default user:
127.0.0.1:6380> auth hello hello
OK
127.0.0.1:6380> publish hello world
(integer) 0
127.0.0.1:6380> acl load
OK
127.0.0.1:6380> publish hello world
(error) NOPERM this user has no permissions to access one of the channels used as arguments
There was a problem hiding this comment.
I think this is a bug we must fix.
it'll change the (buggy) behavior, but i don't see any other way.
i don't think we can document that buggy behavior and keep it (your example above is a clear indication of that).
if we did it'll look something like
when creating a new user that didn't exist before,
acl-pubsub-defaultis respected, but when overriding an existing user, or the default user, all channels are denied unless explicitly allowed.
same goes for reset:
reset Performs the following actions: resetpass, resetkeys, off, resetchannels,
-@all. The user returns to the same state it has immediately
after its creation (except for publish channels that would be denied even when acl-pubsub-default allows them)
this makes no sense.
There was a problem hiding this comment.
@huangzhw , while we're waiting for the core team's approval, if you agree that reset should do that, let's make that change in the PR.
i think it'll conform with the docs, and also be more compatible with redis 6.0.
I suppose something like this should do the trick:
serverAssert(ACLSetUser(u,"resetkeys",-1) == C_OK);
serverAssert(ACLSetUser(u,"resetchannels",-1) == C_OK);
+ if (server.acl_pubusub_default & USER_FLAG_ALLCHANNELS)
+ serverAssert(ACLSetUser(u,"allchannels",-1) == C_OK);There was a problem hiding this comment.
@oranagra Agree. Change made. And I add more tests.
|
@redis/core-team this is a behavior change, please approve or suggest alternative. when considering the behavior change, please consider my suggestion for applying this fix on the |
permissons of channels after reset with different config.
|
Given that this is a new bug in a new feature just recently released, I think it makes total sense to fix it at the cost of a breaking change. |
In the initial release of Redis 6.2 setting a user to only allow pubsub access to a specific channel, and doing ACL SAVE, resulted in an assertion when ACL LOAD was used. This was later changed by #8723 (not yet released), but still not properly resolved (now it errors instead of crash). The problem is that the server that generates an ACL file, doesn't know what would be the setting of the acl-pubsub-default config in the server that will load it. so ACL SAVE needs to always start with resetchannels directive. This should still be compatible with old acl files (from redis 6.0), and ones from earlier versions of 6.2 that didn't mess with channels. Co-authored-by: Harkrishn Patro <[email protected]> Co-authored-by: Oran Agra <[email protected]>
…nels permissions by default. (redis#8723) Background: Redis 6.2 added ACL control for pubsub channels (redis#7993), which were supposed to be permissive by default to retain compatibility with redis 6.0 ACL. But due to a bug, only newly created users got this `acl-pubsub-default` applied, while overwritten (updated) users got reset to `resetchannels` (denied). Since the "default" user exists before loading the config file, any ACL change to it, results in an update / overwrite. So when a "default" user is loaded from config file or include ACL file with no channels related rules, the user will not have any permissions to any channels. But other users will have default permissions to any channels. When upgraded from 6.0 with config rewrite, this will lead to "default" user channels permissions lost. When users are loaded from include file, then call "acl load", users will also lost channels permissions. Similarly, the `reset` ACL rule, would have reset the user to be denied access to any channels, ignoring `acl-pubsub-default` and breaking compatibility with redis 6.0. The implication of this fix is that it regains compatibility with redis 6.0, but breaks compatibility with redis 6.2.0 and 2.0.1. e.g. after the upgrade, the default user will regain access to pubsub channels. Other changes: Additionally this commit rename server.acl_pubusub_default to server.acl_pubsub_default and fix typo in acl tests.
In the initial release of Redis 6.2 setting a user to only allow pubsub access to a specific channel, and doing ACL SAVE, resulted in an assertion when ACL LOAD was used. This was later changed by redis#8723 (not yet released), but still not properly resolved (now it errors instead of crash). The problem is that the server that generates an ACL file, doesn't know what would be the setting of the acl-pubsub-default config in the server that will load it. so ACL SAVE needs to always start with resetchannels directive. This should still be compatible with old acl files (from redis 6.0), and ones from earlier versions of 6.2 that didn't mess with channels. Co-authored-by: Harkrishn Patro <[email protected]> Co-authored-by: Oran Agra <[email protected]>
Background:
Redis 6.2 added ACL control for pubsub channels (#7993), which were supposed
to be permissive by default to retain compatibility with redis 6.0 ACL.
But due to a bug, only newly created users got this
acl-pubsub-defaultapplied,while overwritten (updated) users got reset to
resetchannels(denied).Since the "default" user exists before loading the config file,
any ACL change to it, results in an update / overwrite.
So when a "default" user is loaded from config file or include ACL
file with no channels related rules, the user will not have any
permissions to any channels. But other users will have default
permissions to any channels.
When upgraded from 6.0 with config rewrite, this will lead to
"default" user channels permissions lost.
When users are loaded from include file, then call "acl load", users
will also lost channels permissions.
Similarly, the
resetACL rule, would have reset the user to be deniedaccess to any channels, ignoring
acl-pubsub-defaultand breakingcompatibility with redis 6.0.
The implication of this fix is that it regains compatibility with redis 6.0,
but breaks compatibility with redis 6.2.0 and 6.2.1. e.g. after the upgrade,
the default user will regain access to pubsub channels.
Other changes:
Additionally this commit rename server.acl_pubusub_default to
server.acl_pubsub_default and fix typo in acl tests.