Patch Forecast
Amber warning
Patch this week.

CVE-2026-58273 · GHSA-5j9r-fx4x-rpvg

rucio has an Authorization Bypass on REST API endpoint for signing URLs

Risk score
63/100
CVSS
8.8 v3.1
Published
28 Oct 2026

Open in the live forecast Today's forecast

What to know

What it is
The rucio REST API endpoint for signing URLs has an authorization bypass vulnerability, allowing any client with a valid auth token to mint a presigned URL for an arbitrary object with read, write, and delete permissions.
Affected
{'products': ['rucio'], 'packages': [{'ecosystem': 'pip', 'name': 'rucio', 'vulnerable': '>= 1.16.1, < 35.9.0', 'patched': '35.9.0'}, {'ecosystem': 'pip', 'name': 'rucio', 'vulnerable': '>= 36.0.0rc1, < 38.6.0', 'patched': '38.6.0'}, {'ecosystem': 'pip', 'name': 'rucio', 'vulnerable': '>= 39.0.0rc1, < 41.0.0rc1', 'pat…
Fix
Upgrade to version 35.9.0 or later, or version 38.6.0 or later, or version 41.0.0rc1 or later.
Exploitation
Public proof of concept

Why it is Amber

  • CVSS 8.8 high
  • Public exploit or proof of concept referenced
  • On your watchlist: PyPI

Affected packages

PackageEcosystemVulnerableFixed in
ruciopip>= 1.16.1, < 35.9.035.9.0
ruciopip>= 36.0.0rc1, < 38.6.038.6.0
ruciopip>= 39.0.0rc1, < 41.0.0rc141.0.0rc1

References

Original 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.

Last activity 28 Oct 2026. Patch Forecast updates every hour.