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

Rucio's /credentials/signurl trusts the client-supplied X-Rucio-Account header, letting any low-privilege token holder mint presigned S3/GCS/Swift read/write/delete URLs for arbitrary objects.

- Payout: Research
- Severity: high
- Program: Rucio
- Found by: seankohjs
- Disclosed: 2026-10-28
- CVE: CVE-2026-58273
- Write-up quality: 7/10
- Original: https://github.com/advisories/GHSA-5j9r-fx4x-rpvg
- Library page: https://bugbountylibrary.com/r/ghsa%3AGHSA-5j9r-fx4x-rpvg
- Tags: area:cloud domain:api domain:cloud impact:data-leak impact:integrity kind:research platform:ghsa sev:high tech:s3 technique:source-review vuln:access-control vuln:auth-bypass vuln:idor

**Target:** /credentials/signurl REST endpoint on Rucio server
**Root cause:** SignURL.get() reads the authorization principal from the attacker-controlled X-Rucio-Account header instead of the token-authenticated request.environ['issuer'], so the root-only perm_get_signed_url check passes on a spoofed 'root'. The signing function also never validates that the supplied URL's host/bucket belongs to the target RSE.
**Steps:**
1. Obtain any valid Rucio auth token, including a low-privilege account you own.
2. Send `GET /credentials/signurl?rse=<cloudRSE>&svc=s3&op=delete&url=https://victim-bucket.s3.amazonaws.com/important/dataset.root` with headers `X-Rucio-Auth-Token: <any valid token>` and `X-Rucio-Account: root`.
3. Receive `200 OK` with a presigned DELETE URL signed by the RSE's stored S3 credentials.
4. Replay the presigned URL directly against the storage backend to delete (or read/overwrite) the arbitrary object.
**How found:** Static analysis: noticed credentials.py is the only authenticated handler deriving the account from a request header rather than request.environ['issuer'] set by the token auth hook; confirmed manually.
**Exploitation:** Attacker with any valid token spoofs X-Rucio-Account: root to pass the root-only permission gate, then requests signing for an arbitrary object URL on a cloud-backed RSE; the server signs with its stored S3/GCS/Swift credentials and returns a presigned read/write/delete URL the attacker replays against the backend. In multi-VO, X-Rucio-VO header allows cross-tenant targeting.
**Escalation:** Cross-tenant access in multi-VO deployments via X-Rucio-VO header; arbitrary-object signing oracle extends beyond the target RSE's bucket.
**Insight:** When auditing multi-tenant APIs, grep for handlers that read identity from request headers instead of the auth middleware's resolved principal — a single outlier among many consistent handlers is a strong bypass signal. Also check whether signing/credential-minting endpoints validate that the requested resource belongs to the caller's tenant.

## Proof of concept (copied exactly from the original report)

**Spoofed-account signurl request for arbitrary object**

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

