Hi Redis gurus,

I'm sorry to be a bother, but the below behaviour has me stumped :/

Describe the bug

My goal; disable/deactivate the default user, in-order to limit users to ACL only.

Unfortunately it seems attempts to secure the default user affects the HELLO behaviour for the other ACL users on Redis.

Symptom discovered in v6.0.5, but also reproducible in v6.0.11 & v6.2.

To reproduce Start Redis as outlined below; adding a password to the default user + defining a new ACL user:

root@ab948e714298:/data# redis-server --port 1236 "--user default on >somepw" "--user redisun on >redispw +@all" &
[2] 44
root@ab948e714298:/data# 44:C 25 Feb 2021 09:07:01.224 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
44:C 25 Feb 2021 09:07:01.224 # Redis version=6.2.0, bits=64, commit=00000000, modified=0, pid=44, just started
44:C 25 Feb 2021 09:07:01.224 # Configuration loaded
44:M 25 Feb 2021 09:07:01.225 * monotonic clock: POSIX clock_gettime
                _._
           _.-``__ ''-._
      _.-``    `.  `_.  ''-._           Redis 6.2.0 (00000000/0) 64 bit
  .-`` .-```.  ```\/    _.,_ ''-._
 (    '      ,       .-`  | `,    )     Running in standalone mode
 |`-._`-...-` __...-.``-._|'` _.-'|     Port: 1236
 |    `-._   `._    /     _.-'    |     PID: 44
  `-._    `-._  `-./  _.-'    _.-'
 |`-._`-._    `-.__.-'    _.-'_.-'|
 |    `-._`-._        _.-'_.-'    |           http://redis.io
  `-._    `-._`-.__.-'_.-'    _.-'
 |`-._`-._    `-.__.-'    _.-'_.-'|
 |    `-._`-._        _.-'_.-'    |
  `-._    `-._`-.__.-'_.-'    _.-'
      `-._    `-.__.-'    _.-'
          `-._        _.-'
              `-.__.-'

44:M 25 Feb 2021 09:07:01.226 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
44:M 25 Feb 2021 09:07:01.226 # Server initialized
44:M 25 Feb 2021 09:07:01.227 * Ready to accept connections

Connect via redis-cli

root@ab948e714298:/data# redis-cli -p 1236

Attempt to execute HELLO as the new user

127.0.0.1:1236> HELLO 2 AUTH redisun redispw
(error) NOPERM this user has no permissions to run the 'hello' command or its subcommand

Attempt to execute HELLO as the default user (mostly for completeness)

127.0.0.1:1236> HELLO 2 AUTH default somepw
(error) NOPERM this user has no permissions to run the 'hello' command or its subcommand

Attempt to execute HELLO as the default user by authorising explicitly first

127.0.0.1:1236> AUTH default somepw
OK
127.0.0.1:1236> HELLO 2
(error) NOPERM this user has no permissions to run the 'hello' command or its subcommand

Attempt to execute HELLO as the new user by authorising explicitly first

127.0.0.1:1236> AUTH redisun redispw
OK
127.0.0.1:1236> HELLO 2
 1) "server"
 2) "redis"
 3) "version"
 4) "6.2.0"
 5) "proto"
 6) (integer) 2
 7) "id"
 8) (integer) 3
 9) "mode"
10) "standalone"
11) "role"
12) "master"
13) "modules"
14) (empty array)

In this case, 2 steps are required to get HELLO to work.

Expected behavior

HELLO 2 AUTH redisun redispw

Is expected to work, independently of the default user (or any other user) when redisun is defined in the ACL.

Additional information

Symptom is also present if the the default user is disabled ala --user default off

"Workaround" When only defining a new ACL user, the HELLO behaviour matches expectations. Expect now anyone can now use the default user :/

Start Redis as outlined below, defining a new ACL user:

root@ab948e714298:/data# redis-server --port 1235 "--user redisun on >redispw +@all" &

Connect via redis-cli

root@ab948e714298:/data# redis-cli -p 1235

Attempt to execute HELLO as the new user

127.0.0.1:1235> HELLO 2 AUTH redisun redispw
 1) "server"
 2) "redis"
 3) "version"
 4) "6.2.0"
 5) "proto"
 6) (integer) 2
 7) "id"
 8) (integer) 4
 9) "mode"
10) "standalone"
11) "role"
12) "master"
13) "modules"
14) (empty array)

Attempt to execute HELLO as the default user

127.0.0.1:1235> HELLO
 1) "server"
 2) "redis"
 3) "version"
 4) "6.2.0"
 5) "proto"
 6) (integer) 2
 7) "id"
 8) (integer) 4
 9) "mode"
10) "standalone"
11) "role"
12) "master"
13) "modules"
14) (empty array)
127.0.0.1:1235>

Thanks in advance 🤓

Comment From: hpatro

I also believe this is an issue, HELLO should be treated similar to AUTH and shouldn't get restricted from getting executed.

https://github.com/redis/redis/blob/unstable/src/acl.c#L1185-L1186

As initially the client isn't authenticated in the above scenario, the user is set to default and doesn't have permission to the command it's failing.

@madolson I'm thinking we can handle this in two ways,

  1. Let the command execution if hello command has auth subcommand in it.
  2. The second approach which might be a breaking one is to let the hello command irrespective of auth in it.

Let me know what you think.

Comment From: madolson

Well this is some weird behavior.

@dlehammer Technically you can resolve your issue with: redis-server --port 1236 "--user default off +@all" "--user redisun on >redispw +@all" &

This will prevent users from logging in as default and securing it, but will still let you use hello for auth.

@hpatro I would do #2. The HelloCommand already does special handling for authentication: https://github.com/redis/redis/blob/d828f90c26bf796cb54d6622389e5c14fcc9cbf0/src/networking.c#L2959. I would also use the "CMD_NO_AUTH" flag check instead of checking for the hello command, to allow module authentication to work.

Comment From: dlehammer

Thanks a bunch @madolson, the user default off +@all workaround is sufficient for now - and has been verified on Redis v6.0.5.

I think the key here is whether the HELLO request explicitly includes AUTH ~ as a user I would expect Redis to evaluate the explicit AUTH if present :)

Comment From: itamarhaber

Fixed via #8633 - closing.