Bug 2524516 (CVE-2026-71196)

Summary: CVE-2026-71196 openstack-glance: openstack-glance: SSRF via web-download import due to empty default host filters
Product: [Other] Security Response Reporter: OSIDB Bzimport <bzimport>
Component: vulnerabilityAssignee: Product Security <prodsec-ir-bot>
Status: NEW --- QA Contact:
Severity: high Docs Contact:
Priority: high    
Version: unspecifiedCC: eglynn, jjoyce, jpretori, jschluet, lhh, mburns, mgarciac, security-response-team
Target Milestone: ---Keywords: Security
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: ---
Doc Text:
A server-side request forgery (SSRF) vulnerability was found in OpenStack Glance. The web-download image import method allows authenticated users to provide a URI from which the Glance service fetches data. Due to insufficient default host filtering, an attacker with standard tenant credentials can make Glance issue HTTP requests to arbitrary internal network hosts, including the cloud metadata service. The fetched response is stored as image data and can be downloaded by the attacker, enabling exfiltration of sensitive internal data such as cloud instance credentials.
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-08-26 15:06:34 UTC
OpenStack Glance is the image service for OpenStack. The web-download import method allows authenticated users to supply a URI from which Glance fetches image data server-side. The validate_import_uri() function in glance/common/utils.py (line 225) validates the URI against configurable allow/deny lists for schemes, hosts, and ports. However, the default configuration shipped with Glance has empty allowed_hosts and disallowed_hosts lists, meaning no host filtering is applied. Only scheme filtering (http/https) and port filtering (80/443) are active by default.

The port check in validate_import_uri() (line 270) is bypassed when no explicit port is specified in the URL, because urllib.parse.urlparse returns port=None for URLs using default ports (for example http://169.254.169.254/path), and the check short-circuits on the falsy None value.

This allows any authenticated user with the member role to make Glance issue HTTP/HTTPS requests to arbitrary internal hosts, including the cloud metadata service at 169.254.169.254. Because the fetched bytes become the image payload and are retrievable via GET /v2/images/{image_id}/file, this is a full-read SSRF that can exfiltrate internal service responses including cloud instance credentials.

The vulnerability exists in all versions of Glance that implement the web-download import method with the default import_filtering_opts configuration. The web-download method is enabled by default via enabled_import_methods. Fix is not yet available (coordinating with upstream).

Affected code:
- glance/common/utils.py: validate_import_uri() (lines 225-274)
- glance/async_/flows/_internal_plugins/__init__.py: import_filtering_opts defaults
- glance/async_/flows/_internal_plugins/web_download.py: _WebDownload.execute()
- glance/api/v2/images.py: import_image() entry point

Reporter: Cyril Roelandt (OpenStack Glance PTL / Glance Core Security Team)
Upstream: https://bugs.launchpad.net/glance/+bug/2158998
PSIRT Ticket: PSIRTSUPT-22366
Downstream tracker: OSPRH-32932