Rucio CVE-2026-58273
HIGHAttack ChainAIDerived
Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain
-
AccessObtain any valid low-privilege Rucio token
-
ExploitSend signurl request with spoofed X-Rucio-Account: root
-
ExecutionServer mints presigned S3/GCS/Swift URL
-
ImpactReplay URL to read/overwrite/delete arbitrary objects
Vulnerability Assessment
| Weakness |
CWE
OWASP Top 10:2025
A01:2025 - Broken Access Control
ASVS 5.0
V8 - Authorization Object-level authorization, IDOR prevention
|
| Exploitation Conditions | Requires the attacker to hold any valid Rucio auth token for an account they legitimately own (PR:L - authenticated), plus a target RSE that is cloud-backed with server-stored S3/GCS/Swift credentials; the exploit is the single header X-Rucio-Account: root sent to /credentials/signurl, with no user interaction. In multi-VO deployments the X-Rucio-VO header additionally enables cross-tenant targeting. Limiting factors: a valid token is mandatory (not fully anonymous), the RSE must be configured with cloud storage credentials, and the deployment must run a vulnerable version (>=1.16.1 and <35.9.0, >=36.0.0rc1 and <38.6.0, or >=39.0.0rc1 and <41.0.0rc1). Fixed releases derive the account from the token-authenticated request.environ issuer instead of the header; updating to 35.9.0, 38.6.0, or 41.0.0rc1 is the vendor remedy. |
| Impact | This is a genuine high-priority issue, not a CVSS-inflated one. The vendor CVSS3.1 vector CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H (8.8) is well-supported by the described mechanism: the /credentials/signurl endpoint reads the authorization principal from the attacker-controlled X-Rucio-Account header rather than the token-authenticated identity, so any holder of a valid low-privilege token can assert 'root' and pass the root-only permission check. PR:L is correct because a valid token is required; AC:L is correct because the trigger is a single crafted GET with a spoofed header and needs no special timing or grooming. C:H/I:H/A:H reflect read/write/delete of arbitrary objects via the RSE's stored S3/GCS/Swift credentials. The decision label is 'this_week' and a patch is available across three release branches. No CISA KEV entry and no EPSS score are present in the input, so there is no signal of active or widespread exploitation - exploitation status is therefore driven by the advisory's own proof-of-concept rather than observed attacks. The one metric worth scrutiny is scope: the signed URL acts on cloud storage governed by credentials outside the Rucio server's own authority, which could arguably justify S:C; the vendor kept S:U and this assessment follows that, but defenders should note the real-world blast radius reaches the storage backend itself. |
| Exploit ScenarioDerived | An attacker who legitimately owns any low-privilege Rucio account obtains a normal auth token, then sends a single GET to /credentials/signurl for a cloud-backed RSE while setting the header X-Rucio-Account: root. The server mints a presigned S3/GCS/Swift read, write, or delete URL for an arbitrary bucket/object and returns it, which the attacker replays directly against the storage backend to exfiltrate, overwrite, or destroy data. The advisory includes a concrete PoC request demonstrating a presigned DELETE URL, and the attack is low-complexity and unauthenticated-looking at the application layer beyond needing any valid token. |
Get an e-mail when this CVE is exploited, patched or re-scored. Free account.
Alert meAnalysisAIv1 – Oct 28, 2026
Authorization bypass in the Rucio /credentials/signurl REST endpoint lets any holder of a valid auth token obtain presigned read, write or delete URLs for arbitrary objects in cloud-backed storage. The endpoint performs its root-only permission check against the client-supplied X-Rucio-Account header rather than the token-authenticated identity, so a low-privilege user can simply send X-Rucio-Account: root and have the server sign a URL with the RSE's stored S3/GCS/Swift credentials. Exploitation requires an authenticated account (CVSS PR:L) and a cloud-backed RSE, with no user interaction; the advisory documents a proof-of-concept request, and no active exploitation is confirmed (not in CISA KEV).
RemediationAI
Vendor-released patch: upgrade to 35.9.0, 38.6.0 or 41.0.0rc1 depending on your release branch (https://github.com/rucio/rucio/releases/tag/35.9.0, https://github.com/rucio/rucio/releases/tag/38.6.0, https://github.com/rucio/rucio/releases/tag/41.0.0rc1); the advisory is at https://github.com/rucio/rucio/security/advisories/GHSA-5j9r-fx4x-rpvg and the fixes land in commits 64c0e6a6a93ae88427ff3b7d77532ce08c8a69ec and 8bdc38994a8766658d0314d36afc104c9242c96f, with a third referenced commit 8d9ba31514e6f5dca32b8c1db4738582cb37ec3a. The patched handler stops reading X-Rucio-Account and X-Rucio-VO and instead derives both issuer and VO from the token-authenticated request.environ values, returning HTTP 400 if either is unset; note that this is a behavioral change for any client that relied on supplying the header explicitly. The advisory does not document a workaround, so no configuration-level mitigation is vendor-sanctioned - prioritise upgrading hosts that terminate the /credentials/signurl route, and treat any presigned URLs already issued by vulnerable servers as potentially compromised.
Affected Packages
Source: OSV (Open Source Vulnerabilities)
Affects your stack
Affects 1 package in pypi
Checking this CVE against your own stacks and servers is part of the Basic plan and up.
Technical ContextAI · show details
Rucio is a distributed data-management platform for large-scale scientific data, where storage endpoints (RSEs) may be backed by S3, GCS or Swift and accessed through presigned URLs generated server-side with credentials the server holds. The flaw is CWE-639 (Authorization Bypass Through User-Controlled Key): SignURL.get() in lib/rucio/web/rest/flaskapi/v1/credentials.py reads the principal from request.headers.get('X-Rucio-Account') and passes it to the gateway, which forwards it as issuer to permission.has_permission(action='get_signed_url', ...); the generic permission function perm_get_signed_url returns _is_root(issuer), and an InternalAccount('root', vo).external value of 'root' satisfies that check unconditionally. Although the endpoint sits on AuthenticatedBlueprint, whose before_request hook validates the token and stores the real account in request.environ['issuer'], credentials.py never compares the header to that value - it is the only authenticated handler that trusts the header instead of the authenticated identity. A second weakness in core.credential.get_signed_url means the requested url's host/bucket is never validated against the target RSE, so arbitrary objects can be signed even for a legitimate root caller; in multi-VO deployments the VO is likewise taken from the X-Rucio-VO header, permitting cross-tenant targeting.
Know when Python gets its next vulnerability
- Watch products and get an email when something new is published
- Check this CVE against your own stack and servers
- Exploit and PoC references, threat intelligence from 22 sources
No credit card · 7-day full trial
Severity by source
AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
A valid low-privilege token is required (PR:L) and the trigger is one crafted header-spoofed request (AV:N/AC:L/UI:N); arbitrary read/write/delete of objects yields C:H/I:H/A:H.
Primary rating from GitHub Advisory.
CVSS VectorGitHub Advisory
DescriptionGitHub Advisory
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:
# 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:
# 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:
# 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:
# 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-streamResponse: 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.
Technical POC Analysis
CWE-639 (Authorization Bypass Through User-Controlled Key).
Full technical POC analysis - root cause, step-by-step exploitation and patch breakdown - is part of the Pro and Business plans.
Executive ViewAI
A high-severity authorization bypass in Rucio's signurl endpoint allows any authenticated low-privilege user to obtain presigned URLs granting read, write, or delete access to arbitrary objects in cloud-backed storage. This compromises the confidentiality, integrity, and availability of scientific data stored in S3/GCS/Swift, requiring immediate remediation to protect research assets and institutional reputation.
Apply vendor patch.
Threat Intelligence Overview
How this decision was reached
The engine reads each signal below and applies a fixed list of rules from top to bottom. The first rule that matches sets the recommended action – like a statement, every line is shown.
What every action level means
SSVC AssessmentENISA
Priority Score
Attack Technique
Authentication bypass attacks exploit flaws in the verification mechanisms that control access to systems and applications.
Affected Products (CPE)GitHub Advisory
Wazuh SIEM platform versions 4.4.0 through 4.9.0 contain an unsafe deserialization vulnerability in the DistributedAPI t
BentoML version 1.4.2 and earlier contains an unauthenticated remote code execution vulnerability through insecure deser
pgAdmin 4 contains critical remote code execution vulnerabilities in the Query Tool download and Cloud Deployment endpoi
The renderLocalView function in render/views.py in graphite-web in Graphite 0.9.5 through 0.9.10 uses the pickle Python
BentoML is a Python library for building online serving systems optimized for AI apps and model inference. Rated critica
OpenSSL before 0.9.8za, 1.0.0 before 1.0.0m, and 1.0.1 before 1.0.1h does not properly restrict processing of ChangeCiph
pyLoad download manager version prior to 0.5.0b3.dev77 exposes the Flask SECRET_KEY through an unauthenticated endpoint.
Langflow (a visual LLM pipeline builder) contains a critical unauthenticated code execution vulnerability (CVE-2026-3301
In Mercurial before 4.1.3, "hg serve --stdio" allows remote authenticated users to launch the Python debugger, and conse
Unauthenticated remote code execution affects Kestra OSS (the open-source event-driven orchestration platform) prior to
Unauthenticated remote code execution in Marimo ≤0.20.4 allows attackers to execute arbitrary system commands via the `/
pyLoad is the free and open-source Download Manager written in pure Python. Rated medium severity (CVSS 5.3), this vulne
GHSA-5j9r-fx4x-rpvg
NVD
CVE.org
Exploit-DB