Description
When launching a Docker or OCI worker, the setuid-root `worker-launcher` first changes ownership of the
entire worker directory to the untrusted topology user, and only afterwards reads and acts on the command
file that the supervisor wrote into that same directory. The file is opened without `O_NOFOLLOW` and without
re-verifying its owner, so between the ownership change and the read the tenant can replace its contents.
For the Docker path the parsed command is executed with real uid 0, and the command sanitiser is not a
privilege boundary: it admits `-v` with an arbitrary source, `--device`, `--cap-add`, `--security-opt`,
`--user` and `--net`, and copies positional arguments through verbatim. A rewritten file therefore yields an
attacker-authored, root-equivalent container invocation with the host filesystem available.
For the OCI path the same rewrite window applies, and mount validation is structural only, with no
source or destination allow-list, so arbitrary host paths can be bind-mounted read-write into the
container. The `username` field of the command file is likewise attacker-settable and is checked only
against non-root and minimum-uid rules, permitting execution as another tenant's uid.
Mitigation
Upgrade to 3.1.0, where the command file is validated before the ownership change and re-verified on open,
and where mount sources and destinations are constrained by configuration.
Users who cannot upgrade immediately should disable Docker and OCI worker isolation, or restrict topology
submission on affected supervisors to trusted principals. Note that the launcher must be rebuilt and
reinstalled after upgrading.
Credit
The ASF -- found using Claude agents to study the security of open-source projects, validated and reported by Apache Storm.
Description
`SimpleACLAuthorizer` evaluated the user-level command set by returning early when `nimbus.users` was empty,
before `nimbus.groups` was considered. An operator who restricted cluster access by group alone, leaving
`nimbus.users` unset, therefore received no restriction at all: every authenticated principal was permitted
every user-level operation, including `submitTopology`, `beginFileUpload` and `getNimbusConf`.
`docs/SECURITY.md` presents `nimbus.groups` as a supported way to lock down a cluster, so a deployment
following the documentation could believe it was restricted while it was not. The failure is silent; nothing
in the logs or the configuration indicates that the group list is being ignored.
Both lists left empty continues to mean that no restriction is configured, which is the shipped default and
is unchanged.
Mitigation
Upgrade to 3.1.0, where `nimbus.groups` is evaluated whether or not `nimbus.users` is set.
Users who cannot upgrade immediately should additionally populate `nimbus.users` with the intended
principals, since a non-empty user list causes the group list to be evaluated on affected versions.
Operators should review Nimbus access logs for operations by principals outside the intended groups.
Note that after upgrading, a cluster configured with `nimbus.groups` alone becomes restrictive for the first
time. This includes `NimbusClient`, which calls `getLeader` on every connection, so clients outside the
configured groups will begin to be refused.
Credit
The ASF -- found using Claude agents to study the security of open-source projects, validated and reported by Apache Storm.
Description
`getNimbusConf` returned the complete daemon configuration without redaction after only a user-level
authorization check. Where the cluster is configured with them, that response includes
`storm.zookeeper.auth.payload` and the keystore and truststore passwords for the Thrift, Netty and
ZooKeeper TLS configuration. The project masks passwords elsewhere before display, so the omission here is
inconsistent rather than intended.
The UI endpoint `/api/v1/cluster/configuration` compounded this. It carried no `@AuthNimbusOp` annotation,
and the authorization filter treated a missing annotation as "no gate required" and returned immediately, so
the endpoint applied no per-user check at all and proxied the request under the UI daemon's own principal.
Any user able to pass `ui.filter` therefore received the full configuration, including principals that
Nimbus itself would have refused.
Mitigation
Upgrade to 3.1.0, where credential-bearing values are masked before the configuration is served and where
every UI API endpoint must declare its authorization explicitly.
Users who cannot upgrade immediately should place the UI behind an authenticating reverse proxy that
restricts `/api/v1/cluster/configuration`, and should rotate the ZooKeeper authentication payload and any
TLS keystore or truststore passwords that were reachable through it.
Credit
The ASF -- found using Claude agents to study the security of open-source projects, validated and reported by Apache Storm.
Description
Nimbus validated `topology.blobstore.map` against the calling subject at submission time only. The rebalance
operation accepts configuration overrides and stripped a small set of keys from them, but never re-ran that
validation, so a caller authorised to rebalance a topology could introduce a blobstore map entry naming a
blob whose ACL does not grant them access. Supervisors localise whatever key the map names, placing the
blob's contents into the topology's working directory.
The same advisory covers `listBlobs`, which performed no authorization check and passed no subject, unlike
the neighbouring `getBlobMeta` and `beginBlobDownload` operations. It therefore returned every key in the
blobstore to any caller able to reach the Nimbus Thrift port, which provides the key names that make the
above practical. On its own the disclosure is metadata only.
Mitigation
Upgrade to 3.1.0, where rebalance configuration overrides are validated exactly as submission-time
configuration is, against the rebalancing caller, and where `listBlobs` applies the configured
authorization.
Users who cannot upgrade immediately should restrict rebalance rights to trusted principals, keeping in mind
that membership of a topology's `topology.users` or `topology.groups` confers them.
Credit
The ASF -- found using Claude agents to study the security of open-source projects, validated and reported by Apache Storm.
Description
When ZooKeeper authentication is configured, Storm deliberately retains
`storm.zookeeper.topology.auth.payload` in the topology configuration, because workers need it. Nimbus then
served that configuration verbatim to any caller holding read-only topology permissions, so a user whose
only grant was the ability to view a topology received its ZooKeeper credential.
That credential is not read-only. The cluster state implementation uses write-capable ACLs for worker
heartbeats, backpressure and error state, so a recipient can forge or remove that state for the topology
concerned. It is not a write credential on assignments.
The same advisory covers the submission client, which logged the generated payload at INFO on every
submission that generated one, and the SASL handlers, which logged it at DEBUG. The credential therefore
also reached any log aggregation or support bundle collected from the cluster.
Mitigation
Upgrade to 3.1.0, where the payload is removed from the configuration served to read-only callers and is no
longer written to logs.
Users who cannot upgrade immediately should rotate `storm.zookeeper.topology.auth.payload` for existing
topologies, review retained logs and support bundles for the value, and restrict read-only topology
permissions to trusted principals.
Credit
The ASF -- found using Claude agents to study the security of open-source projects, validated and reported by Apache Storm.
Description
The worker's Netty message decoder is installed ahead of the SASL authentication handlers in the pipeline
and acts on frames before any authentication has taken place. It allocated buffers sized from a
length field carried in the frame, so a single frame from an unauthenticated peer able to reach a worker
slot port could drive a large allocation.
`storm.messaging.netty.authentication` defaults to false, and the decoder runs before the handler that
enforces it in any case, so no credentials are required. The attacker needs only TCP reachability to a
worker port.
The effect of a single frame at the default 768 MB worker heap has not been measured to distinguish
sustained worker loss from transient garbage-collection pressure. The severity assigned to this advisory
reflects the more conservative reading; consumers who require a precise figure should test against their own
worker heap configuration.
Mitigation
Upgrade to 3.1.0, where frames are decoded only after the handshake completes.
Users who cannot upgrade immediately should ensure that worker slot ports are reachable only from within the
cluster, as the security model already recommends, and should enable
`storm.messaging.netty.authentication` where the deployment permits it.
Credit
The ASF -- found using Claude agents to study the security of open-source projects, validated and reported by Apache Storm.
Description
The Logviewer offers `logs.users` and `logs.groups` so operators can control who may read log content. For
daemon logs those settings were not applied: the access decision combined the "this is a daemon log" flag
with the authorizer result in a way that discarded the authorizer's answer whenever the flag was set, and
the daemon log page and download endpoints reached the handler without consulting an authorizer at all. Any
user able to pass the configured servlet filter could therefore read `nimbus.log`, `supervisor.log` and the
other daemon logs on every reachable node, which contain other tenants' topology names, owners and
configuration fragments.
The same advisory covers the log listing endpoints, which accepted a user argument and never applied it, so
`/listLogs` and `/searchLogs` returned every tenant's topology and worker log file names regardless of the
caller. That part is metadata only.
There was no configuration that closed either behaviour.
Mitigation
Upgrade to 3.1.0, where the daemon log paths evaluate the same configured user and group lists that the
worker log paths already used, and the listing endpoints filter by the requesting user.
Users who cannot upgrade immediately should place the Logviewer behind a reverse proxy that restricts the
daemon log endpoints, and should treat daemon log content as readable by any filter-authenticated user.
Credit
The ASF -- found using Claude agents to study the security of open-source projects, validated and reported by Apache Storm.
Description
Nimbus accepted the `uploadedJarLocation` argument of `submitTopology` / `submitTopologyWithOpts` as a
server-side path and opened it directly, without checking that it referred to a file the caller had
actually uploaded. The intended flow is that a client first calls `beginFileUpload`, which returns a path
inside the Nimbus inbox, and uploads the jar in chunks to that location; nothing bound submission to that
flow, and the `uploaders` map populated by `beginFileUpload` was never consulted at submit time.
An authenticated user with topology submission rights could therefore submit any path readable by the
Nimbus daemon user as their topology jar. Nimbus copied the file into the topology's jar blob, and the
blob ACL grants the submitting subject read access, so the contents could then be retrieved with the
ordinary blob download RPCs. Candidate targets include the Nimbus Kerberos keytab, Thrift and UI TLS
private keys, and `storm.yaml` with the ZooKeeper authentication payload. Possession of the Nimbus keytab
turns an ordinary tenant into a cluster administrator.
In a deployment configured as the documentation recommends, submission is available to every
authenticated principal when `nimbus.users` is unset, so no elevated privilege is required.
Mitigation
Upgrade to 3.1.0, where the submitted location is canonicalised and must resolve inside the Nimbus inbox.
Users who cannot upgrade immediately should restrict topology submission to trusted principals via
`nimbus.users` or `nimbus.groups`, and should treat any file readable by the Nimbus daemon user as
potentially exposed to submitters: rotate the Nimbus keytab and any TLS private keys or ZooKeeper
credentials reachable from that account. Local mode is unaffected.
Credit
Independently reported to the Apache Storm PMC by n0mi1k, with a proof of concept.
Also found by the ASF using Claude agents to study the security of open-source projects, validated and reported by Apache Storm.
Description
Three separate mechanisms allowed a web page on an unrelated origin to read responses that Storm's HTTP
components served to an authenticated user.
The Logviewer reflected the request's `Origin` header back in `Access-Control-Allow-Origin` while also
sending `Access-Control-Allow-Credentials: true`. The published security model documents a permissive
`Access-Control-Allow-Origin: *` posture as accepted, which is safe precisely because browsers refuse to
honour `*` together with credentials; reflecting the concrete origin removes that protection.
The shared CORS filter used by the UI, the Logviewer and DRPC was configured with a response header name
where an initialisation parameter name was expected. The container ignored the setting and applied its own
defaults, which allow credentials.
Finally, the UI and Logviewer wrapped API responses in a caller-supplied JSONP callback for every GET
request. A script element on any origin can load such a response, which bypasses the same-origin policy
entirely rather than negotiating it, and there was no way to turn the behaviour off.
In each case the effect is that a page visited by an authenticated operator can read cluster, topology and
log data on their behalf.
Mitigation
Upgrade to 3.1.0, where the Logviewer no longer reflects the request origin in a credentialed response, the
CORS filter is configured explicitly, and JSONP wrapping is governed by `ui.enable.jsonp`, which defaults to
false.
Note that disabling JSONP is a behaviour change for tooling that passes a `callback` query parameter; such
tooling should be moved to ordinary JSON requests.
Users who cannot upgrade immediately should place the UI, Logviewer and DRPC HTTP endpoints behind a reverse
proxy that strips `Access-Control-Allow-Origin` and `Access-Control-Allow-Credentials` from responses and
rejects requests carrying a `callback` parameter.
Credit
The ASF -- found using Claude agents to study the security of open-source projects, validated and reported by Apache Storm.
Description
The DRPC server kept a map from function name to request queue and created an entry the first time a
function name was seen. No code path ever removed an entry: request cleanup removed the request from its
queue, and the shutdown path drained queues, but the queue object and its map entry remained for the life of
the process.
Function names come from the client and are not constrained to functions any topology has registered, so the
number of retained entries is bounded only by the number of distinct names an attacker chooses to send, and
each retained entry holds the name itself. `drpc.authorizer` is unset by default, so no credentials are
required to reach the endpoint.
The retained state is permanent rather than a transient load spike, so the effect accumulates until the DRPC
server exhausts its heap.
Mitigation
Upgrade to 3.1.0, where a function's queue is removed once nothing is waiting in it.
Users who cannot upgrade immediately should configure `drpc.authorizer` so that only trusted principals can
reach the DRPC endpoints, and should ensure the DRPC ports are not reachable from untrusted networks.
Credit
The ASF -- found using Claude agents to study the security of open-source projects, validated and reported by Apache Storm.
Description
A submitted topology carries two lists of blobstore keys, `dependency_jars` and `dependency_artifacts`,
which the client fills in after uploading the corresponding blobs. Nimbus performed no validation of their
contents on the submission path, yet acts on them in two places.
During cleanup of a finished topology, Nimbus deletes the keys named in those lists, and the deletion is
performed as the Nimbus subject, for which the blobstore short-circuits its ACL check. A submitter who
listed a key belonging to another topology, such as its `-stormjar.jar`, could therefore cause
that blob to be deleted when their own topology was cleaned up.
Separately, on acquiring leadership a Nimbus compares the dependency keys of all active topologies against
the blobstore contents and surrenders leadership if any is missing. A single key that does not exist, on a
single active topology, therefore causes every Nimbus to acquire leadership, surrender it and requeue
indefinitely, leaving the cluster without a leader and unable to schedule, clean up or accept submissions.
Mitigation
Upgrade to 3.1.0, where a submission is refused unless every entry in both lists is a dependency blob key
and exists in the blobstore.
Note that this validates new submissions only; a topology stored by an affected version with an invalid list
is unaffected by the upgrade. An operator whose cluster is failing to retain a leader should inspect the
Nimbus log for the dependency keys reported as missing and remove or resubmit the topology naming them.
Users who cannot upgrade immediately should restrict topology submission to trusted principals.
Credit
This issue was discovered by rzo1 while investigating an unrelated blobstore defect.
Description
getTopologyPageInfo merged the Nimbus daemon configuration with the topology's own configuration and returned the result without redaction in the topology_conf field of TopologyPageInfo. The Storm UI copied that value verbatim into the configuration field of GET /api/v1/topology/{id} and of the corresponding metrics endpoint.
Where the cluster is configured with them, the merged map includes storm.zookeeper.auth.payload, which Storm's own documentation directs operators to keep in storm-cluster-auth.yaml under permissions that deny access from workers, together with the keystore and truststore passwords for the Thrift, Netty and ZooKeeper TLS configuration, and any plugin key whose name denotes a secret.
getTopologyPageInfo is a topology read-only operation. Under SimpleACLAuthorizer a principal listed in topology.readonly.users or topology.readonly.groups could therefore read daemon credentials that the dedicated cluster configuration API, getNimbusConf, redacts and that is gated on nimbus.users instead. The sibling operations that exist to serve configuration were masked; the topology page, which merges in strictly more daemon state, was not.
Mitigation
Upgrade to 3.1.0, where credential-bearing values are masked before any configuration is served over the Nimbus API.
Users who cannot upgrade immediately should remove any principal that is not trusted with cluster credentials from topology.readonly.users, topology.readonly.groups, topology.users and topology.groups, and should rotate the ZooKeeper authentication payload and any TLS keystore or truststore passwords that were reachable through the topology page.
Credit
Wanxin Yin (yaklang.io) reported this issue to the Apache Security Team.
URL Redirection to Untrusted Site ('Open Redirect') vulnerability in Apache Syncope.
When the Syncope SRA is configured for CAS authentication, the target Apereo CAS instance's URL is calculated by unconditionally looking at client-supplied forwarded HTTP headers.
This issue affects Apache Syncope: from 3.0.0-M0 through 3.0.16, from 4.0.0-M0 Through 4.0.7, from 4.1.0-M0 through 4.1.2.
Users are recommended to upgrade to version 4.0.8 / 4.1.3, which fix this issue.
Improper Encoding or Escaping of Output vulnerability in Apache Syncope.
Authenticated users can store a spreadsheet formula payload in one of their own plain attributes. When such users are included in a CSV export and the generated CSV file is opened by a spreadsheet application, the formula may be executed.
This issue affects Apache Syncope: from 3.0.0-M0 through 3.0.16, from 4.0.0-M0 Through 4.0.7, from 4.1.0-M0 through 4.1.2.
Users are recommended to upgrade to version 4.0.8 / 4.1.3, which fix this issue.
Incorrect Authorization vulnerability in Apache Syncope.
Delegated administration security checks are based on Realm hierarchy and enforced via prefix matches.
Due to incorrect implementation, two sibling Realms whose names begin with the same string cannot be correctly distinguished, resulting in incorrect authorization.
This issue affects Apache Syncope: from 3.0.0-M0 through 3.0.16, from 4.0.0-M0 Through 4.0.7, from 4.1.0-M0 through 4.1.2.
Users are recommended to upgrade to version 4.0.8 / 4.1.3, which fix this issue.
Incorrect Authorization vulnerability in Apache Syncope.
Delegated administration security checks performed by Reconciliation service's pull and push, being incomplete, could accept calls by administrator not provided with adequate entitlements.
This issue affects Apache Syncope: from 3.0.0-M0 through 3.0.16, from 4.0.0-M0 Through 4.0.7, from 4.1.0-M0 through 4.1.2.
Users are recommended to upgrade to version 4.0.8 / 4.1.3, which fix this issue.
Exposure of Sensitive Information to an Unauthorized Actor vulnerability in Apache Syncope.
An administrator with adequate entitlements can get access via REST to the list of existing Access Tokens, including their signed JWT body.
These values can be then used to perform further REST requests, impersonating users with higher administration entitlements.
This issue affects Apache Syncope: from 3.0.0-M0 through 3.0.16, from 4.0.0-M0 Through 4.0.7, from 4.1.0-M0 through 4.1.2.
Users are recommended to upgrade to version 4.0.8 / 4.1.3, which fix this issue.
Improper Privilege Management vulnerability in Apache Syncope.
Delegations can be created or updated with Roles not owned by the delegating User, or not for the same Realm subtree under the delegation management was granted for.
This issue affects Apache Syncope: from 3.0.0-M0 through 3.0.16, from 4.0.0-M0 Through 4.0.7, from 4.1.0-M0 through 4.1.2.
Users are recommended to upgrade to version 4.0.8 / 4.1.3, which fix this issue.
Incorrect Authorization vulnerability in Apache Syncope.
Any search requests are transformed into SQL, Neo4J or Elasticsearch / Opensearch queries, depending on the actual deployment configuration.
An important component of such transformation is the Realms filter, which ensures that the search results are matching the requester's permissions.
For non-recursive search requests it is possible that such Realms filter is rendered as empty, thus voiding any restriction on requester privileges.
This issue affects Apache Syncope: from 3.0.0-M0 through 3.0.16, from 4.0.0-M0 Through 4.0.7, from 4.1.0-M0 through 4.1.2.
Users are recommended to upgrade to version 4.0.8 / 4.1.3, which fix this issue.
Insufficiently Protected Credentials vulnerability in Apache Syncope.
Audit events, when sent to the configured store, are not sufficiently masked for the sensitive values they might carry on their payloads, thus allowing administrators to access such sensitive values.
This issue affects Apache Syncope: from 3.0.0-M0 through 3.0.16, from 4.0.0-M0 Through 4.0.7, from 4.1.0-M0 through 4.1.2.
Users are recommended to upgrade to version 4.0.8 / 4.1.3, which fix this issue.