Bug 2528221 (CVE-2026-85471)

Summary: CVE-2026-85471 quay: quay: Webhook notification SSRF -- hostname-string blocklist trivially bypassable
Product: [Other] Security Response Reporter: OSIDB Bzimport <bzimport>
Component: vulnerabilityAssignee: Product Security <prodsec-ir-bot>
Status: NEW --- QA Contact:
Severity: medium Docs Contact:
Priority: medium    
Version: unspecifiedCC: aruklets, doconnor, security-response-team
Target Milestone: ---Keywords: Security
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: ---
Doc Text:
A flaw was found in Quay. An authenticated repository administrator could bypass the hostname blacklist in webhook notifications, leading to a Server-Side Request Forgery (SSRF) vulnerability. This allows the Quay application to be tricked into sending requests to internal network resources, such as cloud metadata services or other services within the cluster. Consequently, this could lead to the disclosure of sensitive information from these internal services.
Story Points: ---
Clone Of: Environment:
Last Closed: Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description OSIDB Bzimport 2026-09-03 20:07:13 UTC
## Webhook notification SSRF: hostname-string blocklist trivially bypassable

**CWEs:** CWE-918
**CVSS:** 6.4 (CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:L/A:N)
**Component:** quay/quay

### Description
`HOSTNAME_BLACKLIST = ["localhost", "127.0.0.1"]` extended by `WEBHOOK_HOSTNAME_BLACKLIST` (default `[]`, `config.py:840`). `WebhookMethod.validate()` and `.perform()` test only `urlparse(url).hostname.lower() in HOSTNAME_BLACKLIST` before `requests.post(url, ...)`. No DNS resolution, no IP-range check, no use of `util/security/ssrf.py`. Any repo admin (i.e. any authenticated tenant on their own repo) can target `169.254.169.254`, `0.0.0.0`, `[::1]`, `127.0.0.2`, decimal/octal IP encodings, or an attacker DNS name resolving to RFC1918/link-local. Response body is logged on non-2xx (`resp.content`), giving a partial oracle.

**Impact**: blind/semi-blind POST SSRF to cloud-metadata and in-cluster services from the Quay pod network namespace.

### Affected Locations
- `notifications/notificationmethod.py:22-23,213,236,253`

### Attack Pattern
A repo admin configures a webhook notification pointing at an internal/metadata address using an encoding that evades the hostname string blocklist, causing the Quay pod to issue an authenticated-context POST to that internal target and expose limited response information via logged non-2xx bodies.

### Remediation
Route all webhook target validation through `util/security/ssrf.py` (DNS resolution + IP-range blocklist, not hostname string matching), consistent with the proxy-cache and mirror validators.

### Note
This finding shares its root cause class (missing SSRF validation in `notifications`/`proxy`/`workers/repomirrorworker`) with CVE-2026-32591 (already public, fixed). The CVSS vector/score above was computed independently -- the original audit did not provide one.

---
*Source: Ex-Wing security assessment, finding QUAY-001*