CVE-2026-48013
Shopware: SSRF in Media External-Link Endpoint Bypasses IP Validation
CVE-2026-48013 is a medium vulnerability (CVSS 4.1) in Runzero Platform, published June 4, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.37%, the 30th percentile. Fixed in shopware/core 6.7.10.1.
Shopware is an open commerce platform. Prior to 6.6.10.18 and 6.7.10.1, the /api/_action/media/external-link endpoint allows authenticated admin users to make server-side HTTP HEAD requests to arbitrary internal IP addresses. While the parallel uploadFromURL flow validates target IPs against private/reserved ranges via FileUrlValidator, the linkURL flow only performs a URL format check (regex for http:// or https:// prefix), allowing SSRF to internal network services and cloud metadata endpoints. This issue is fixed in versions 6.6.10.18 and 6.7.10.1.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- High
- User interaction
- None
What an attacker can affect
- Confidentiality
- Low
- Integrity
- None
- Availability
- None
Exploit likelihood
What each source reports
CVE List Score used
4.1
Shopware: SSRF in Media External-Link Endpoint Bypasses IP Validation
Shopware is an open commerce platform. Prior to 6.6.10.18 and 6.7.10.1, the /api/_action/media/external-link endpoint allows authenticated admin users to make server-side HTTP HEAD requests to arbitrary internal IP addresses. While the parallel uploadFromURL flow validates target IPs against private/reserved ranges via FileUrlValidator, the linkURL flow only performs a URL format check (regex for http:// or https:// prefix), allowing SSRF to internal network services and cloud metadata endpoints. This issue is fixed in versions 6.6.10.18 and 6.7.10.1.
- Record
CVE-2026-48013- CVSS 3.1
- 4.1 Medium
CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:C/C:L/I:N/A:N - Weakness
- CWE-918, CWE-918
- Updated
- 2026-11-02
EUVDEUVD-2026-48378
4.1
Shopware is an open commerce platform. Prior to 6.6.10.18 and 6.7.10.1, the /api/_action/media/external-link endpoint allows authenticated admin users to make server-side HTTP HEAD requests to arbitrary internal IP addresses. While the parallel uploadFromURL flow validates target IPs against private/reserved ranges via FileUrlValidator, the linkURL flow only performs a URL format check (regex for http:// or https:// prefix), allowing SSRF to internal network services and cloud metadata endpoints. This issue is fixed in versions 6.6.10.18 and 6.7.10.1.
- Record
EUVD-2026-48378- CVSS 3.1
- 4.1 Medium
CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:C/C:L/I:N/A:N - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-gq96-5pfx-f4vc
4.1
Shopware: SSRF in Media External-Link Endpoint Bypasses IP Validation
Summary
The /api/_action/media/external-link endpoint allows authenticated admin users to make server-side HTTP HEAD requests to arbitrary internal IP addresses. While the parallel uploadFromURL flow validates target IPs against private/reserved ranges via FileUrlValidator, the linkURL flow only performs a URL format check (regex for http:// or https:// prefix), allowing SSRF to internal network services and cloud metadata endpoints.
Details
The vulnerability is an inconsistency between two URL-handling flows in MediaUploadService.
Vulnerable path (external-link):
MediaUploadV2Controller::externalLink() at src/Core/Content/Media/Api/MediaUploadV2Controller.php:66 takes a user-supplied url parameter and passes it to MediaUploadService::linkURL() at src/Core/Content/Media/Upload/MediaUploadService.php:134.
linkURL() calls getContentSizeFromValidExternalUrl($url) at line 159, which only validates via validateExternalUrl():
// src/Core/Content/Media/Upload/MediaUploadService.php:207-212
public static function validateExternalUrl(string $url): void
{
if (!preg_match('/^https?:\/\/.+/', $url)) {
throw MediaException::invalidUrl($url);
}
}
Then makes a server-side HEAD request with no IP filtering:
// src/Core/Content/Media/Upload/MediaUploadService.php:292-300
private function getContentSizeFromValidExternalUrl(string $url): int
{
$this->validateExternalUrl($url);
$headers = $this->httpClient->request('HEAD', $url)->getHeaders();
if (!\array_key_exists('content-length', $headers)) {
throw MediaException::fileNotFound($url);
}
return (int) $headers['content-length'][0];
}
Protected path (upload_by_url):
In contrast, uploadFromURL uses FileFetcher::fetchFromURL() which calls FileUrlValidator::isValid():
// src/Core/Content/Media/File/FileFetcher.php:64
if ($this->enableUrlValidation && !$this->fileUrlValidator->isValid($url)) {
throw MediaException::illegalUrl($url);
}
FileUrlValidator::isValid() resolves the hostname via gethostbyname() and validates the IP against private and reserved ranges using filter_var() with FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE. This protection is entirely absent from the linkURL flow.
Impact
An authenticated admin user can:
- Probe cloud metadata services — HEAD requests to
169.254.169.254reveal whether cloud metadata endpoints exist and leak content-length values - Scan internal networks — Differentiate open/closed/filtered ports on internal hosts (10.x, 172.16.x, 192.168.x) based on response timing and error types
- Leak internal service information — The
fileSizefield stored in the database reflects thecontent-lengthheader from internal services - Redirect-based escalation — Symfony HttpClient follows redirects by default (max_redirects=20), allowing an attacker-controlled external server to redirect the HEAD request to arbitrary internal destinations
Impact is limited to information disclosure via HEAD requests. The admin authentication requirement (PR:H) reduces exploitability, but in multi-tenant or compromised-credential scenarios this allows network reconnaissance from the server's perspective.
Recommended Fix
Apply FileUrlValidator to the linkURL flow, consistent with the uploadFromURL flow. In MediaUploadService:
// src/Core/Content/Media/Upload/MediaUploadService.php
// Add constructor dependency:
private readonly FileUrlValidatorInterface $fileUrlValidator;
// In getContentSizeFromValidExternalUrl(), add IP validation:
private function getContentSizeFromValidExternalUrl(string $url): int
{
$this->validateExternalUrl($url);
if (!$this->fileUrlValidator->isValid($url)) {
throw MediaException::illegalUrl($url);
}
$headers = $this->httpClient->request('HEAD', $url)->getHeaders();
if (!\array_key_exists('content-length', $headers))…
- Record
GHSA-gq96-5pfx-f4vc- CVSS 3.1
- 4.1 Medium
CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:C/C:L/I:N/A:N - Weakness
- CWE-918
- Updated
- 2026-11-02
NVD
4.1
Shopware is an open commerce platform. Prior to 6.6.10.18 and 6.7.10.1, the /api/_action/media/external-link endpoint allows authenticated admin users to make server-side HTTP HEAD requests to arbitrary internal IP addresses. While the parallel uploadFromURL flow validates target IPs against private/reserved ranges via FileUrlValidator, the linkURL flow only performs a URL format check (regex for http:// or https:// prefix), allowing SSRF to internal network services and cloud metadata endpoints. This issue is fixed in versions 6.6.10.18 and 6.7.10.1.
- Record
CVE-2026-48013- CVSS 3.1
- 4.1 Medium
CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:C/C:L/I:N/A:N - Weakness
- CWE-918
- Updated
- 2026-11-02
OSV
4.1
Shopware: SSRF in Media External-Link Endpoint Bypasses IP Validation
Shopware is an open commerce platform. Prior to 6.6.10.18 and 6.7.10.1, the /api/_action/media/external-link endpoint allows authenticated admin users to make server-side HTTP HEAD requests to arbitrary internal IP addresses. While the parallel uploadFromURL flow validates target IPs against private/reserved ranges via FileUrlValidator, the linkURL flow only performs a URL format check (regex for http:// or https:// prefix), allowing SSRF to internal network services and cloud metadata endpoints. This issue is fixed in versions 6.6.10.18 and 6.7.10.1.
- Record
CVE-2026-48013- CVSS 3.1
- 4.1 Medium
CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:C/C:L/I:N/A:N - Weakness
- CWE-918
- Updated
- 2026-11-02
OSVGHSA-gq96-5pfx-f4vc
4.1
Shopware: SSRF in Media External-Link Endpoint Bypasses IP Validation
Summary
The /api/_action/media/external-link endpoint allows authenticated admin users to make server-side HTTP HEAD requests to arbitrary internal IP addresses. While the parallel uploadFromURL flow validates target IPs against private/reserved ranges via FileUrlValidator, the linkURL flow only performs a URL format check (regex for http:// or https:// prefix), allowing SSRF to internal network services and cloud metadata endpoints.
Details
The vulnerability is an inconsistency between two URL-handling flows in MediaUploadService.
Vulnerable path (external-link):
MediaUploadV2Controller::externalLink() at src/Core/Content/Media/Api/MediaUploadV2Controller.php:66 takes a user-supplied url parameter and passes it to MediaUploadService::linkURL() at src/Core/Content/Media/Upload/MediaUploadService.php:134.
linkURL() calls getContentSizeFromValidExternalUrl($url) at line 159, which only validates via validateExternalUrl():
// src/Core/Content/Media/Upload/MediaUploadService.php:207-212
public static function validateExternalUrl(string $url): void
{
if (!preg_match('/^https?:\/\/.+/', $url)) {
throw MediaException::invalidUrl($url);
}
}
Then makes a server-side HEAD request with no IP filtering:
// src/Core/Content/Media/Upload/MediaUploadService.php:292-300
private function getContentSizeFromValidExternalUrl(string $url): int
{
$this->validateExternalUrl($url);
$headers = $this->httpClient->request('HEAD', $url)->getHeaders();
if (!\array_key_exists('content-length', $headers)) {
throw MediaException::fileNotFound($url);
}
return (int) $headers['content-length'][0];
}
Protected path (upload_by_url):
In contrast, uploadFromURL uses FileFetcher::fetchFromURL() which calls FileUrlValidator::isValid():
// src/Core/Content/Media/File/FileFetcher.php:64
if ($this->enableUrlValidation && !$this->fileUrlValidator->isValid($url)) {
throw MediaException::illegalUrl($url);
}
FileUrlValidator::isValid() resolves the hostname via gethostbyname() and validates the IP against private and reserved ranges using filter_var() with FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE. This protection is entirely absent from the linkURL flow.
Impact
An authenticated admin user can:
- Probe cloud metadata services — HEAD requests to
169.254.169.254reveal whether cloud metadata endpoints exist and leak content-length values - Scan internal networks — Differentiate open/closed/filtered ports on internal hosts (10.x, 172.16.x, 192.168.x) based on response timing and error types
- Leak internal service information — The
fileSizefield stored in the database reflects thecontent-lengthheader from internal services - Redirect-based escalation — Symfony HttpClient follows redirects by default (max_redirects=20), allowing an attacker-controlled external server to redirect the HEAD request to arbitrary internal destinations
Impact is limited to information disclosure via HEAD requests. The admin authentication requirement (PR:H) reduces exploitability, but in multi-tenant or compromised-credential scenarios this allows network reconnaissance from the server's perspective.
Recommended Fix
Apply FileUrlValidator to the linkURL flow, consistent with the uploadFromURL flow. In MediaUploadService:
// src/Core/Content/Media/Upload/MediaUploadService.php
// Add constructor dependency:
private readonly FileUrlValidatorInterface $fileUrlValidator;
// In getContentSizeFromValidExternalUrl(), add IP validation:
private function getContentSizeFromValidExternalUrl(string $url): int
{
$this->validateExternalUrl($url);
if (!$this->fileUrlValidator->isValid($url)) {
throw MediaException::illegalUrl($url);
}
$headers = $this->httpClient->request('HEAD', $url)->getHeaders();
if (!\array_key_exists('content-length', $headers))…
- Record
GHSA-gq96-5pfx-f4vc- CVSS 3.1
- 4.1 Medium
CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:C/C:L/I:N/A:N - Weakness
- CWE-918
- Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
shopware/corePackagist |
6.7.0.0 up to 6.7.10.1 | 6.7.10.1 |
shopware/platformPackagist |
6.7.0.0 up to 6.7.10.1 | 6.7.10.1 |
shopware/corePackagist |
6.7.0.0 up to 6.7.10.1, plus listed versions v6.7.0.0v6.7.0.1v6.7.1.0v6.7.1.1v6.7.1.2 Show 21 moreShow lessv6.7.10.0v6.7.2.0v6.7.2.1v6.7.2.2v6.7.3.0v6.7.3.1v6.7.4.0v6.7.4.1v6.7.4.2v6.7.5.0v6.7.5.1v6.7.6.0v6.7.6.1v6.7.6.2v6.7.7.0v6.7.7.1v6.7.8.0v6.7.8.1v6.7.8.2v6.7.9.0v6.7.9.1 |
6.7.10.1 |
shopware/platformPackagist |
6.7.0.0 up to 6.7.10.1, plus listed versions v6.7.0.0v6.7.0.1v6.7.1.0v6.7.1.1v6.7.1.2 Show 21 moreShow lessv6.7.10.0v6.7.2.0v6.7.2.1v6.7.2.2v6.7.3.0v6.7.3.1v6.7.4.0v6.7.4.1v6.7.4.2v6.7.5.0v6.7.5.1v6.7.6.0v6.7.6.1v6.7.6.2v6.7.7.0v6.7.7.1v6.7.8.0v6.7.8.1v6.7.8.2v6.7.9.0v6.7.9.1 |
6.7.10.1 |
History
| When | Changed | Sources |
|---|---|---|
| 2026-11-02 | created | CVE List, EUVD, GitHub Advisories, NVD, OSV |
References
github.com/shopware/shopware/security/advisories/GHSA-gq96-5pfx-f4vc
github.com/shopware/shopware/releases/tag/v6.6.10.18
github.com/shopware/shopware/releases/tag/v6.7.10.1
github.com/advisories/GHSA-gq96-5pfx-f4vc
github.com/CVEProject/cvelistV5/tree/main/cves/2026/48xxx/CVE-2026-48013.json
nvd.nist.gov/vuln/detail/CVE-2026-48013
github.com/shopware/shopware
Left out here: the rest of 2 source descriptions. The JSON record has them.