Every CVE Search/ Get API key

CVE-2026-58273

Rucio: Authorisation Bypass on REST API endpoint for signing URLs

8.1 HighFix available

Rucio is a scientific data management framework. From 1.16.1 until 35.9.0, 38.6.0, and 41.0.0rc1, the /credentials/signurl endpoint reads X-Rucio-Account instead of the account stored in request.environ['issuer'] by token authentication. Any authenticated low-privilege user can supply root as the header value and pass the root-only get_signed_url permission check. The server then returns a presigned read, write, or delete URL for an attacker-selected object using stored S3, GCS, or Swift credentials, and X-Rucio-VO can select another tenant in multi-VO deployments. This permits data disclosure, modification, deletion, and cross-tenant access on cloud-backed RSEs. This issue is fixed in versions 35.9.0, 38.6.0, and 41.0.0rc1.

Attack profile

How easy it is to exploit

Attack vector
Network
Complexity
Low
Privileges needed
Low
User interaction
None

What an attacker can affect

Confidentiality
High
Integrity
High
Availability
None

Exploit likelihood

0.56%Unchanged since Nov 6, 2026
90%50%10%1%

What each source reports

CVE List Score used 8.1

Rucio: Authorisation Bypass on REST API endpoint for signing URLs

Rucio is a scientific data management framework. From 1.16.1 until 35.9.0, 38.6.0, and 41.0.0rc1, the /credentials/signurl endpoint reads X-Rucio-Account instead of the account stored in request.environ['issuer'] by token authentication. Any authenticated low-privilege user can supply root as the header value and pass the root-only get_signed_url permission check. The server then returns a presigned read, write, or delete URL for an attacker-selected object using stored S3, GCS, or Swift credentials, and X-Rucio-VO can select another tenant in multi-VO deployments. This permits data disclosure, modification, deletion, and cross-tenant access on cloud-backed RSEs. This issue is fixed in versions 35.9.0, 38.6.0, and 41.0.0rc1.

Record
CVE-2026-58273
CVSS 3.1
8.1 HighCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N
Weakness
CWE-639
Updated
2026-11-06
EUVDEUVD-2026-117819 8.1

Rucio is a scientific data management framework. From 1.16.1 until 35.9.0, 38.6.0, and 41.0.0rc1, the /credentials/signurl endpoint reads X-Rucio-Account instead of the account stored in request.environ['issuer'] by token authentication. Any authenticated low-privilege user can supply root as the header value and pass the root-only get_signed_url permission check. The server then returns a presigned read, write, or delete URL for an attacker-selected object using stored S3, GCS, or Swift credentials, and X-Rucio-VO can select another tenant in multi-VO deployments. This permits data disclosure, modification, deletion, and cross-tenant access on cloud-backed RSEs. This issue is fixed in versions 35.9.0, 38.6.0, and 41.0.0rc1.

Record
EUVD-2026-117819
CVSS 3.1
8.1 HighCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N
Updated
2026-11-06
GitHub AdvisoriesGHSA-5j9r-fx4x-rpvg 8.8

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

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

Record
GHSA-5j9r-fx4x-rpvg
CVSS 3.1
8.8 HighCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
Weakness
CWE-639
Updated
2026-11-02
NVD 8.1

Rucio is a scientific data management framework. From 1.16.1 until 35.9.0, 38.6.0, and 41.0.0rc1, the /credentials/signurl endpoint reads X-Rucio-Account instead of the account stored in request.environ['issuer'] by token authentication. Any authenticated low-privilege user can supply root as the header value and pass the root-only get_signed_url permission check. The server then returns a presigned read, write, or delete URL for an attacker-selected object using stored S3, GCS, or Swift credentials, and X-Rucio-VO can select another tenant in multi-VO deployments. This permits data disclosure, modification, deletion, and cross-tenant access on cloud-backed RSEs. This issue is fixed in versions 35.9.0, 38.6.0, and 41.0.0rc1.

Record
CVE-2026-58273
CVSS 3.1
8.1 HighCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N
Weakness
CWE-639
Updated
2026-11-06
OSV 8.1

Rucio: Authorisation Bypass on REST API endpoint for signing URLs

Rucio is a scientific data management framework. From 1.16.1 until 35.9.0, 38.6.0, and 41.0.0rc1, the /credentials/signurl endpoint reads X-Rucio-Account instead of the account stored in request.environ['issuer'] by token authentication. Any authenticated low-privilege user can supply root as the header value and pass the root-only get_signed_url permission check. The server then returns a presigned read, write, or delete URL for an attacker-selected object using stored S3, GCS, or Swift credentials, and X-Rucio-VO can select another tenant in multi-VO deployments. This permits data disclosure, modification, deletion, and cross-tenant access on cloud-backed RSEs. This issue is fixed in versions 35.9.0, 38.6.0, and 41.0.0rc1.

Record
CVE-2026-58273
CVSS 3.1
8.1 HighCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N
Weakness
CWE-639
Updated
2026-11-07
OSVGHSA-5j9r-fx4x-rpvg 8.8

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

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

Record
GHSA-5j9r-fx4x-rpvg
CVSS 3.1
8.8 HighCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
Weakness
CWE-639
Updated
2026-11-02

Affected products

Affected packages

Affected packages
PackageAffectedFixed
rucio
PyPI
1.16.1 up to 35.9.0
35.9.0
rucio
PyPI
36.0.0rc1 up to 38.6.0
38.6.0
rucio
PyPI
39.0.0rc1 up to 41.0.0rc1
41.0.0rc1
rucio
PyPI
1.16.1 up to 35.9.0, plus listed versions
1.16.21.16.31.17.01.17.11.17.2
Show 45 moreShow less
1.17.2.post11.17.51.17.61.17.6.post11.17.6.post21.17.71.17.81.17.8.post11.17.8.post21.18.01.18.11.18.31.18.41.18.51.18.5.post11.18.61.18.6.post11.18.71.18.81.18.8.post11.18.91.19.0.post21.19.11.19.31.19.41.19.4.post11.19.4.post21.19.51.19.61.19.71.19.7.post11.19.81.20.01.20.0rc11.20.11.20.1.post11.20.101.20.111.20.121.20.131.20.141.20.151.20.161.20.21.20.3
35.9.0
rucio
PyPI
36.0.0rc1 up to 38.6.0, plus listed versions
36.0.036.0.0.post136.0.0.post236.0.0rc236.0.0rc3
Show 35 moreShow less
36.0.0rc436.0.0rc536.1.036.2.036.3.036.4.036.5.037.0.037.0.0rc137.0.0rc237.0.0rc337.0.0rc437.1.037.1.0.post137.2.037.3.037.4.037.5.037.6.037.7.037.7.138.0.038.0.0rc138.0.0rc238.0.0rc338.1.038.2.038.3.038.4.038.5.038.5.138.5.238.5.338.5.438.5.5
38.6.0
rucio
PyPI
39.0.0rc1 up to 41.0.0rc1, plus listed versions
39.0.039.0.0rc239.1.039.2.039.3.0
Show 14 moreShow less
39.3.139.4.039.4.139.4.240.0.040.0.0rc140.1.040.1.140.1.240.2.040.3.040.4.040.4.140.4.2
41.0.0rc1

History

History
RecordedChangedSources
referencesCVE List
referencesOSV
aliasesEUVD, NVD
description, facts, products, references, severity, titleCVE List
first indexedGitHub Advisories, OSV

Dates are when Every CVE recorded each change. Upstream dates may differ.

In short

CVE-2026-58273 is a high vulnerability (CVSS 8.1) in Rucio, published October 28, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.56%, the 46th percentile. Fixed in rucio 35.9.0.

References

Show 5 moreShow less
This page doesn't list everything

Left out here: 274 versions. The JSON record has them.

MoveEnter Open