CVE-2026-28385
SSRF via image import from URL allows internal network probing by authenticated users
In Canonical LXD versions 4.12 through 6.9, a Server-Side Request Forgery (SSRF) vulnerability in the image import functionality allows authenticated users with the can_create_images entitlement to interact with internal network infrastructure via the /images endpoint. When importing an image from a URL source, the LXD daemon fails to validate or restrict outbound destination IP addresses, allowing connections to loopback, RFC1918 private ranges, and cloud metadata endpoints. This enables error-based port scanning and unauthorized interaction with internal HTTP services from the daemon's network position.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- Low
- User interaction
- None
What an attacker can affect
- Confidentiality
- Low
- Integrity
- None
- Availability
- None
Exploit likelihood
What each source reports
CVE List Score used
5.0
SSRF via image import from URL allows internal network probing by authenticated users
In Canonical LXD versions 4.12 through 6.9, a Server-Side Request Forgery (SSRF) vulnerability in the image import functionality allows authenticated users with the can_create_images entitlement to interact with internal network infrastructure via the /images endpoint. When importing an image from a URL source, the LXD daemon fails to validate or restrict outbound destination IP addresses, allowing connections to loopback, RFC1918 private ranges, and cloud metadata endpoints. This enables error-based port scanning and unauthorized interaction with internal HTTP services from the daemon's network position.
- Record
CVE-2026-28385- CVSS 3.1
- 5.0 Medium
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:N/A:N - Weakness
- CWE-918
- Updated
- 2026-11-02
EUVDEUVD-2026-39805
5.0
LXD: SSRF via image import from URL allows internal network probing by authenticated users
- Record
EUVD-2026-39805- CVSS 3.1
- 5.0 Medium
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:N/A:N - Updated
- 2026-11-06
GitHub AdvisoriesGHSA-3gq2-x4qg-p4g6
5.0
LXD: SSRF via image import from URL allows internal network probing by authenticated users
Summary
The LXD image import-from-URL endpoint (POST /1.0/images with source.type=url) makes server-side HTTP requests to an attacker-supplied URL without any private-IP or loopback blocking. An authenticated user with the can_create_images entitlement can force the LXD daemon to connect to internal network addresses (127.0.0.1, RFC1918 ranges, cloud metadata endpoints), enabling port scanning via error-based inference and interaction with internal HTTP services from the daemon's privileged network position.
Severity
- Attack Vector: Network — LXD API is network-accessible.
- Attack Complexity: Low — Single crafted API request with no special conditions.
- Privileges Required: Low — Requires
can_create_imagesentitlement, a non-admin permission commonly delegated to regular users. - User Interaction: None.
- Scope: Changed — The attacker leverages LXD's privileged network position to probe and interact with internal services that are outside the attacker's direct network access and outside the scope of LXD's image management authorization.
- Confidentiality Impact: Low — Error messages reveal internal port states (open/closed/filtered) and service availability. Response bodies from internal services are NOT returned to the attacker (hash validation blocks content exfiltration).
- Integrity Impact: None — No demonstrated ability to modify data on internal services.
- Availability Impact: None — No meaningful resource exhaustion or denial of service.
Affected Component
lxd/images.go—imgPostURLInfo(lines 668–755) — Makes HEAD request to user-supplied URL without any SSRF protections.lxd/util/http.go—HTTPClient(lines 102–147) — Creates HTTP client with no IP blocking or URL validation.shared/network.go—RFC3493Dialer(lines 20–49) — Dials arbitrary hosts including private/loopback ranges.lxd/daemon_images.go—ImageDownload(lines 478–510, "direct" case) — Makes GET request to URL from attacker-controlled response header.
Description
Core vulnerability: no SSRF protections on server-side image fetching
When a user imports an image from a URL, the imgPostURLInfo function makes an HTTP HEAD request directly to the user-supplied URL with zero validation:
// lxd/images.go:668-703
func imgPostURLInfo(ctx context.Context, s *state.State, req api.ImagesPost, ...) (*api.Image, error) {
if req.Source.URL == "" {
return nil, errors.New("Missing URL")
}
myhttp, err := util.HTTPClient("", s.Proxy)
// ...
// Resolve the image URL
head, err := http.NewRequest("HEAD", req.Source.URL, nil)
// No URL validation, no scheme check, no IP range check
// ...
raw, err := myhttp.Do(head) // Makes request to arbitrary destination
The HTTP client is created via util.HTTPClient which uses shared.RFC3493Dialer — a standard dialer with zero private-IP filtering:
// shared/network.go:20-49
func RFC3493Dialer(context context.Context, network string, address string) (net.Conn, error) {
host, port, err := net.SplitHostPort(address)
// ...
addrs, err := net.LookupHost(host)
// ...
for _, a := range addrs {
c, err := net.DialTimeout(network, net.JoinHostPort(a, port), 10*time.Second)
// No check: IsLoopback? IsPrivate? IsLinkLocalUnicast?
// Connects to ANY resolved address including 127.0.0.1, 10.x.x.x, 169.254.169.254
The HTTP client also follows redirects unconditionally:
// lxd/util/http.go:139-144
myhttp.CheckRedirect = func(req *http.Request, via []*http.Request) error {
// Replicate the headers
req.Header = via[len(via)-1].Header
return nil // Always follows redirects — no destination validation
}
No SSRF protections exist anywhere in the codebase
An exhaustive search for private-IP checks (IsLoopback, IsPrivate, IsLinkLocalUnicast), URL allowlists, or SSRF-specific…
- Record
GHSA-3gq2-x4qg-p4g6- CVSS 3.1
- 5.0 Medium
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:N/A:N - Weakness
- CWE-918
- Updated
- 2026-11-06
NVD
5.0
In Canonical LXD versions 4.12 through 6.9, a Server-Side Request Forgery (SSRF) vulnerability in the image import functionality allows authenticated users with the can_create_images entitlement to interact with internal network infrastructure via the /images endpoint. When importing an image from a URL source, the LXD daemon fails to validate or restrict outbound destination IP addresses, allowing connections to loopback, RFC1918 private ranges, and cloud metadata endpoints. This enables error-based port scanning and unauthorized interaction with internal HTTP services from the daemon's network position.
- Record
CVE-2026-28385- CVSS 3.1
- 5.0 Medium
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:N/A:N - Weakness
- CWE-918
- Updated
- 2026-11-02
OSV
5.0
SSRF via image import from URL allows internal network probing by authenticated users
In Canonical LXD versions 4.12 through 6.9, a Server-Side Request Forgery (SSRF) vulnerability in the image import functionality allows authenticated users with the can_create_images entitlement to interact with internal network infrastructure via the /images endpoint. When importing an image from a URL source, the LXD daemon fails to validate or restrict outbound destination IP addresses, allowing connections to loopback, RFC1918 private ranges, and cloud metadata endpoints. This enables error-based port scanning and unauthorized interaction with internal HTTP services from the daemon's network position.
- Record
CVE-2026-28385- CVSS 3.1
- 5.0 Medium
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:N/A:N - Weakness
- CWE-918
- Updated
- 2026-11-02
OSVDEBIAN-CVE-2026-28385
5.0
In Canonical LXD versions 4.12 through 6.9, a Server-Side Request Forgery (SSRF) vulnerability in the image import functionality allows authenticated users with the can_create_images entitlement to interact with internal network infrastructure via the /images endpoint. When importing an image from a URL source, the LXD daemon fails to validate or restrict outbound destination IP addresses, allowing connections to loopback, RFC1918 private ranges, and cloud metadata endpoints. This enables error-based port scanning and unauthorized interaction with internal HTTP services from the daemon's network position.
- Record
DEBIAN-CVE-2026-28385- CVSS 3.1
- 5.0 Medium
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:N/A:N - Updated
- 2026-11-02
OSVGHSA-3gq2-x4qg-p4g6
5.0
LXD: SSRF via image import from URL allows internal network probing by authenticated users
Summary
The LXD image import-from-URL endpoint (POST /1.0/images with source.type=url) makes server-side HTTP requests to an attacker-supplied URL without any private-IP or loopback blocking. An authenticated user with the can_create_images entitlement can force the LXD daemon to connect to internal network addresses (127.0.0.1, RFC1918 ranges, cloud metadata endpoints), enabling port scanning via error-based inference and interaction with internal HTTP services from the daemon's privileged network position.
Severity
- Attack Vector: Network — LXD API is network-accessible.
- Attack Complexity: Low — Single crafted API request with no special conditions.
- Privileges Required: Low — Requires
can_create_imagesentitlement, a non-admin permission commonly delegated to regular users. - User Interaction: None.
- Scope: Changed — The attacker leverages LXD's privileged network position to probe and interact with internal services that are outside the attacker's direct network access and outside the scope of LXD's image management authorization.
- Confidentiality Impact: Low — Error messages reveal internal port states (open/closed/filtered) and service availability. Response bodies from internal services are NOT returned to the attacker (hash validation blocks content exfiltration).
- Integrity Impact: None — No demonstrated ability to modify data on internal services.
- Availability Impact: None — No meaningful resource exhaustion or denial of service.
Affected Component
lxd/images.go—imgPostURLInfo(lines 668–755) — Makes HEAD request to user-supplied URL without any SSRF protections.lxd/util/http.go—HTTPClient(lines 102–147) — Creates HTTP client with no IP blocking or URL validation.shared/network.go—RFC3493Dialer(lines 20–49) — Dials arbitrary hosts including private/loopback ranges.lxd/daemon_images.go—ImageDownload(lines 478–510, "direct" case) — Makes GET request to URL from attacker-controlled response header.
Description
Core vulnerability: no SSRF protections on server-side image fetching
When a user imports an image from a URL, the imgPostURLInfo function makes an HTTP HEAD request directly to the user-supplied URL with zero validation:
// lxd/images.go:668-703
func imgPostURLInfo(ctx context.Context, s *state.State, req api.ImagesPost, ...) (*api.Image, error) {
if req.Source.URL == "" {
return nil, errors.New("Missing URL")
}
myhttp, err := util.HTTPClient("", s.Proxy)
// ...
// Resolve the image URL
head, err := http.NewRequest("HEAD", req.Source.URL, nil)
// No URL validation, no scheme check, no IP range check
// ...
raw, err := myhttp.Do(head) // Makes request to arbitrary destination
The HTTP client is created via util.HTTPClient which uses shared.RFC3493Dialer — a standard dialer with zero private-IP filtering:
// shared/network.go:20-49
func RFC3493Dialer(context context.Context, network string, address string) (net.Conn, error) {
host, port, err := net.SplitHostPort(address)
// ...
addrs, err := net.LookupHost(host)
// ...
for _, a := range addrs {
c, err := net.DialTimeout(network, net.JoinHostPort(a, port), 10*time.Second)
// No check: IsLoopback? IsPrivate? IsLinkLocalUnicast?
// Connects to ANY resolved address including 127.0.0.1, 10.x.x.x, 169.254.169.254
The HTTP client also follows redirects unconditionally:
// lxd/util/http.go:139-144
myhttp.CheckRedirect = func(req *http.Request, via []*http.Request) error {
// Replicate the headers
req.Header = via[len(via)-1].Header
return nil // Always follows redirects — no destination validation
}
No SSRF protections exist anywhere in the codebase
An exhaustive search for private-IP checks (IsLoopback, IsPrivate, IsLinkLocalUnicast), URL allowlists, or SSRF-specific…
- Record
GHSA-3gq2-x4qg-p4g6- CVSS 3.1
- 5.0 Medium
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:N/A:N - Weakness
- CWE-918
- Updated
- 2026-11-06
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
github.com/canonical/lxdGo |
before 0.0.0-20261005133302-c4a919f3f4e2 | 0.0.0-20261005133302-c4a919f3f4e2 |
lxdDebian:12 |
All versions, plus listed versions 5.0.2+git20231211.1364ae4-15.0.2+git20231211.1364ae4-25.0.2+git20231211.1364ae4-35.0.2+git20231211.1364ae4-45.0.2+git20231211.1364ae4-5 Show 12 moreShow less5.0.2+git20231211.1364ae4-65.0.2+git20231211.1364ae4-75.0.2+git20231211.1364ae4-85.0.2+git20231211.1364ae4-95.0.2-55.0.2-5+deb12u15.0.2-5+deb12u25.0.2-5+deb12u35.0.2-5+deb12u45.0.2-5+deb12u55.0.2-5+deb12u65.0.2-6 |
None known |
lxdDebian:13 |
All versions, plus listed versions 5.0.2+git20231211.1364ae4-95.0.2+git20231211.1364ae4-9+deb13u15.0.2+git20231211.1364ae4-9+deb13u25.0.2+git20231211.1364ae4-9+deb13u35.0.2+git20231211.1364ae4-9+deb13u45.0.2+git20231211.1364ae4-9+deb13u55.0.2+git20231211.1364ae4-9+deb13u65.0.2+git20231211.1364ae4-9+deb13u7 |
None known |
History
| Recorded | Changed | Sources |
|---|---|---|
| published | EUVD | |
| affected, references | OSV | |
| affected, facts, references | GitHub Advisories | |
| first indexed | CVE List, EUVD, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-28385 is a medium vulnerability (CVSS 5.0) in Canonical Lxd, published June 26, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.28%, the 20th percentile. Fixed in github.com/canonical/lxd 0.0.0-20261005133302-c4a919f3f4e2.
References
github.com/canonical/lxd/security/advisories/GHSA-3gq2-x4qg-p4g6
github.com/canonical/lxd/pull/18462
nvd.nist.gov/vuln/detail/CVE-2026-28385
github.com/canonical/lxd/pull/18210
github.com/canonical/lxd/commit/08996fa031eebc2bc2f8e27148c2ba24386c01d0
github.com/canonical/lxd/commit/4bbdb17ab67010446668e4b00a5175df5b6d55b4
Show 12 moreShow less
github.com/canonical/lxd/commit/5976c92117b79d73437d7fab55e34cb80083edff
github.com/canonical/lxd/commit/886fcf5b7686bf59de78e239cec90a69e8fb9c65
github.com/canonical/lxd/commit/c4a919f3f4e21249d535d4030a33484313026111
github.com/canonical/lxd/blob/lxd-6.10.0/lxd/image_source_transitional.go
github.com/canonical/lxd/blob/lxd-6.9/lxd/daemon_images.go
github.com/canonical/lxd/blob/lxd-6.9/lxd/images.go
github.com/canonical/lxd/releases/tag/lxd-6.9
github.com/advisories/GHSA-3gq2-x4qg-p4g6
github.com/canonical
github.com/CVEProject/cvelistV5/tree/main/cves/2026/28xxx/CVE-2026-28385.json
github.com/canonical/lxd
security-tracker.debian.org/tracker/CVE-2026-28385
Left out here: the rest of 2 source descriptions. The JSON record has them.