nats-io / nats-server

High-Performance server for NATS.io, the cloud and edge native messaging system.
https://nats.io
Apache License 2.0
15.92k stars 1.41k forks source link

security: JetStream KeyValue: The direct set and get API allows bypassing the permissions on the key value stores. #5203

Closed bjorndm closed 8 months ago

bjorndm commented 8 months ago

Observed behavior

I have a user with the following permissions: who should be able to fetch one key from a bucket, but not write to that bucket or that key:

Account Information

                           User: rdm@example.com
                        Account: APP
                        Expires: never
                      Client ID: 114
                      Client IP: 127.0.0.1
                            RTT: 224µs
              Headers Supported: true
                Maximum Payload: 1.0 MiB
                  Connected URL: nats://localhost:4222
              Connected Address: 127.0.0.1:4222
            Connected Server ID: NC2KWFO6OGCLTMB3G6MDSXZ2CNCBOITAAUSJ64Z6746CDYX26U5ZJSM5
       Connected Server Version: 2.10.7
                 TLS Connection: no

Connection Permissions:

                            Allow: $JS.>
                                   $SYS.REQ.USER.INFO
                                   _INBOX.>

   Subscribe:
                            Allow: $JS.>
                                   $KV.user_v1.org_bdm
                                   _INBOX.>

JetStream Account Information:

Account Usage:

                        Storage: 100 B
                         Memory: 0 B
                        Streams: 1
                      Consumers: 0

Account Limits:

            Max Message Payload: 1.0 MiB

  Tier: Default:

      Configuration Requirements:

        Stream Requires Max Bytes Set: false
         Consumer Maximum Ack Pending: Unlimited

      Stream Resource Usage Limits:

                               Memory: 0 B of Unlimited
                    Memory Per Stream: Unlimited
                              Storage: 100 B of Unlimited
                   Storage Per Stream: Unlimited
                              Streams: 1 of Unlimited
                            Consumers: 0 of Unlimited

This then works, while I feel it should not:

nats --user="rdm@example.com" --password="[REDACTED]" -s localhost:4222 kv put user_v1 org_bdm '{key:"org_bdm", name: "BDM"}'
{key:"org_bdm", name: "edited"}

Expected behavior

It should give access denied.

While it makes sense that the user has access to the JetStream API, it doesn't make sense that the server doesn't check the permissions of the user to the KV bucket itself. While this can be bypassed by limiting access to the JetStream API topics, this workaround is quite cumbersome, especially if there are many buckets and many keys, and because there are several JetStream API needed to access a bucket and get or set a key.

Server and client version

nats-server --version nats-server: v2.10.7 nats --version 0.1.1

Host environment

MacOS

Steps to reproduce

No response

bjorndm commented 8 months ago

I noticed that I had make a mistake in the permissions in my system. It actually does work correctly. Sorry for the noise.