CVE-2026-58273: rucio has an Authorization Bypass on REST API endpoint for signing URLs
Affects rucioSource GCVE Database
Not known to be exploited · CVSS 8.8 High : upgrade to 35.9.0 soon.
Data as of 28 Oct 2026, 21:14 UTC
- Patch
- Available – fixed in 35.9.0, 38.6.0, 41.0.0rc1
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:HExploitation evidence
Disclosed: evidence found.
CVE published 28 Oct 2026
Detectable: no evidence on record.
No public nuclei template indexed
Weaponised: no evidence on record.
No public exploit code indexed in Metasploit or Exploit-DB
Exploited in the wildExploited: no evidence on record.
Not in CISA KEV and no source reports exploitation
Observed by OffSeq MirageSeen by Mirage: no evidence on record.
No attack traffic recorded by OffSeq Mirage sensors
A missing step is not evidence of safety. Sources: cve.org (opens in a new tab), the Metasploit, Exploit-DB and nuclei-templates index as of 26 Oct 2026.
What to do
Upgrade rucio to 35.9.0; rucio to 38.6.0; rucio to 41.0.0rc1.
Affected software
| Product | Affected | Fixed in |
|---|---|---|
| PyPIrucio | Affected
| Fixed in
|
| PyPIrucio | Affected
| Fixed in
|
| PyPIrucio | Affected
| Fixed in
|
Check your own hosts for these packages with threat-finder (opens in a new tab), our free open-source scanner.
Description
## Summary The `/credentials/signurl` endpoint decides authorization from the client-supplied `X-Rucio-Account` HTTP header instead of the authenticated token's account. Any client holding **any** valid auth token (even a low-privilege account they legitimately own) can send `X-Rucio-Account: root` to pass the root-only permission check and have the Rucio server mint a presigned **read / write / delete** URL for an **arbitrary** object, signed with the RSE's stored S3 / GCS / Swift credentials. ## Details `SignURL.get()` takes the authorization principal from a request header and never uses the token-authenticated identity: ```python # lib/rucio/web/rest/flaskapi/v1/credentials.py account = request.headers.get('X-Rucio-Account', default=None) # L165 (attacker-controlled) ... result = get_signed_url(account, rse=rse, service=service, # L194 operation=operation, url=url, lifetime=lifetime, vo=vo) ``` The gateway then uses that header value as the `issuer` for the permission check: ```python # lib/rucio/gateway/credential.py auth_result = permission.has_permission(issuer=account, vo=vo, # L57 action='get_signed_url', kwargs=kwargs, ...) ``` and the permission function is root-only: ```python # lib/rucio/core/permission/generic.py def perm_get_signed_url(issuer, kwargs, session): return _is_root(issuer) # _is_root(x) -> x.external == 'root' ``` `InternalAccount('root', vo).external == 'root'` unconditionally, so the gate passes whenever the header is `root`. The endpoint is on `AuthenticatedBlueprint`, whose `before_request` hook validates the token and sets `request.environ['issuer']` **from the token** — but nothing ever compares `X-Rucio-Account` to it: ```python # lib/rucio/web/rest/flaskapi/v1/common.py (request_auth_env) flask.request.environ['issuer'] = auth.get('account') # L168 (the real account; unused by SignURL) ``` This is anomalous: every other authenticated handler derives the account from `request.environ['issuer']`; `credentials.py` is the only one that trusts the header. Additionally, `core.credential.get_signed_url` never checks that the supplied `url`'s host/bucket belongs to the target RSE, so even a legitimate `root` caller gets an arbitrary-object signing oracle. In multi-VO the VO is also read from the `X-Rucio-VO` header, allowing cross-tenant targeting. ## Proof of concept Request (any valid token + spoofed account): ``` GET /credentials/signurl?rse=<cloudRSE>&svc=s3&op=delete&url=https://victim-bucket.s3.amazonaws.com/important/dataset.root HTTP/1.1 X-Rucio-Auth-Token: <any valid token, even a low-privilege account> X-Rucio-Account: root Accept: application/octet-stream ``` Response: `200 OK` with a presigned DELETE URL the attacker replays directly against the storage backend. ## Impact A low-privilege Rucio user can read, overwrite, and delete arbitrary objects on any cloud-backed (S3/GCS/Swift) RSE using the server's stored credentials — enabling data exfiltration, tampering, and destruction, and cross-tenant access in multi-VO deployments. ## Credit Reported by seankohjs. Found via static analysis + manual verification.
References
- github.com/rucio/rucio/security/advisories/GHSA-5j9r-fx4x-rpvg (opens in a new tab)
- github.com/rucio/rucio/commit/64c0e6a6a93ae88427ff3b7d77532ce08c8a69ec (opens in a new tab)
- github.com/rucio/rucio/commit/8bdc38994a8766658d0314d36afc104c9242c96f (opens in a new tab)
- github.com/rucio/rucio/commit/8d9ba31514e6f5dca32b8c1db4738582cb37ec3a (opens in a new tab)
- github.com/rucio/rucio (opens in a new tab)
- github.com/rucio/rucio/releases/tag/35.9.0 (opens in a new tab)
- github.com/rucio/rucio/releases/tag/38.6.0 (opens in a new tab)
- github.com/rucio/rucio/releases/tag/41.0.0rc1 (opens in a new tab)