CVE-2026-25492
PHP vulnerability analysis and mitigation

Overview

CVE-2026-25492 is a Server-Side Request Forgery (SSRF) vulnerability in Craft CMS affecting the save_images_Asset GraphQL mutation. It allows authenticated attackers to bypass hostname validation by supplying a domain name that resolves to an internal IP address (e.g., the AWS EC2 metadata endpoint 169.254.169.254), enabling exfiltration of sensitive internal data such as AWS IAM credentials. Affected versions are Craft CMS 3.5.0 through 4.16.17 and 5.0.0-RC1 through 5.8.21. The vulnerability was disclosed and patched on February 9, 2026. It carries a CVSS v3.1 base score of 6.5 (Medium) and a CVSS v4.0 base score of 5.3 (Medium) (GitHub Advisory).

Technical details

The root cause is CWE-918 (Server-Side Request Forgery): the handleUpload() method in src/gql/resolvers/mutations/Asset.php validates that the supplied URL uses a hostname rather than a raw IP address, but does not resolve the hostname to check whether it maps to a private or cloud-metadata IP. An attacker registers a domain (e.g., attacker.domain) with a DNS A record pointing to 169.254.169.254 (AWS instance metadata service), bypassing the filter_var($hostname, FILTER_VALIDATE_IP) check. Additionally, specifying a non-image file extension such as .txt in the filename parameter bypasses downstream image-format validation, allowing arbitrary content (e.g., credential JSON) to be saved and retrieved as a static asset. Exploitation requires network access to the GraphQL endpoint, a valid bearer token with save_images_Asset mutation permissions, and .txt (or another non-image extension) being permitted for uploads — which is the default configuration (GitHub Advisory, Patch Commit).

Impact

Successful exploitation allows an authenticated attacker to retrieve sensitive data from the internal network of the host running Craft CMS, most critically AWS EC2 instance metadata credentials (IAM role access keys and session tokens) from 169.254.169.254. These credentials can be used to pivot into the broader AWS environment, enabling lateral movement, privilege escalation, or data exfiltration beyond the Craft CMS application itself. There is no integrity or availability impact; the vulnerability is purely a confidentiality breach, but the potential for cloud infrastructure compromise significantly elevates its real-world severity (GitHub Advisory).

Exploitability

A proof-of-concept (PoC) Python script is publicly available in the official GitHub Security Advisory, demonstrating the full attack chain. There is no evidence of active in-the-wild exploitation at this time, and no threat actor attribution has been reported. The EPSS score is approximately 0.012% (4th percentile), indicating low current exploitation probability. The vulnerability is not listed in the CISA Known Exploited Vulnerabilities (KEV) catalog (GitHub Advisory).

Exploitation steps

  1. Reconnaissance: Identify a Craft CMS instance running a vulnerable version (3.5.0–4.16.17 or 5.0.0-RC1–5.8.21) with GraphQL enabled and accessible. Confirm the target is hosted on a cloud provider (e.g., AWS EC2) where instance metadata is available at 169.254.169.254.
  2. Obtain GraphQL credentials: Acquire a valid GraphQL bearer token with permissions to invoke the save_images_Asset mutation — either through a compromised account, a stolen token, or as a malicious insider.
  3. Set up attacker-controlled domain: Register a domain (e.g., attacker.domain) and configure its DNS A record to resolve to the target internal IP, such as 169.254.169.254 (AWS metadata) or another sensitive internal address.
  4. Craft the malicious GraphQL mutation: Send a POST request to the GraphQL endpoint (/actions/graphql/api) with the save_images_Asset mutation, setting url to http://attacker.domain/latest/meta-data/iam/security-credentials and filename to foo.txt.
  5. Trigger server-side fetch: Craft CMS resolves attacker.domain to 169.254.169.254, fetches the AWS metadata credentials on the attacker's behalf, and saves the response as /assets/images/foo.txt.
  6. Retrieve exfiltrated data: Issue a standard HTTP GET request to http://<target>/assets/volumes/images/foo.txt to download the AWS IAM role credentials (access key ID, secret access key, session token).
  7. Leverage credentials: Use the obtained AWS credentials to authenticate to AWS APIs and perform lateral movement, privilege escalation, or data exfiltration within the cloud environment (GitHub Advisory).

Indicators of compromise

  • Network: Outbound HTTP requests from the Craft CMS server to 169.254.169.254 or other cloud metadata IPs (169.254.170.2, 100.100.100.200, 192.0.0.192); DNS lookups for attacker-controlled domains resolving to RFC 1918 or link-local addresses.
  • Logs: Craft CMS access logs showing POST requests to /actions/graphql/api with save_images_Asset mutation payloads containing unusual url parameters (external domains) and non-image filename values (e.g., .txt, .json); subsequent GET requests to /assets/volumes/images/*.txt shortly after.
  • File System: Unexpected non-image files (e.g., .txt, .json) appearing in the Craft CMS assets/images directory, particularly with names like foo.txt or containing AWS credential-like content (JSON with AccessKeyId, SecretAccessKey, Token fields).
  • Application: GraphQL mutation logs (if enabled) recording save_images_Asset calls with external URL parameters pointing to domains not associated with legitimate content sources (GitHub Advisory).

Mitigation and workarounds

Upgrade Craft CMS to version 4.16.18 (for the 4.x branch) or 5.8.22 (for the 5.x branch), which resolve the SSRF by adding DNS-resolution-based validation that checks whether a hostname resolves to known cloud metadata IPs, and by blocklisting known internal metadata hostnames such as metadata.google.internal and kubernetes.default (Patch Commit, Release 5.8.22). If immediate upgrade is not possible, restrict GraphQL save_images_Asset mutation permissions to only highly trusted users, disable .txt and other non-image file extensions in upload settings, and implement network-level controls (e.g., firewall rules or IMDSv2 enforcement on AWS) to block server-side access to 169.254.169.254 from the web application host (GitHub Advisory).

Community reactions

The vulnerability was reported by researcher LeftenantZero and published by angrybrad via the Craft CMS GitHub Security Advisory on February 9, 2026. No significant broader media coverage or notable public researcher commentary beyond the official advisory has been identified at this time (GitHub Advisory).

Additional resources


SourceThis report was generated using AI

Related PHP vulnerabilities:

CVE ID

Severity

Score

Technologies

Component name

CISA KEV exploit

Has fix

Published date

CVE-2026-47156CRITICAL9.3
  • PHP logoPHP
  • mantisbt/mantisbt
NoYesSep 09, 2026
CVE-2026-85400HIGH7.5
  • PHP logoPHP
  • cpe:2.3:a:typo3:typo3
NoYesSep 08, 2026
CVE-2026-53637MEDIUM6.5
  • PHP logoPHP
  • sylius/sylius
NoYesSep 08, 2026
CVE-2026-53639MEDIUM6.3
  • PHP logoPHP
  • sylius/sylius
NoYesSep 08, 2026
CVE-2026-53638MEDIUM4.3
  • PHP logoPHP
  • sylius/sylius
NoYesSep 08, 2026

Free Vulnerability Assessment

Benchmark your Cloud Security Posture

Evaluate your cloud security practices across 9 security domains to benchmark your risk level and identify gaps in your defenses.

Request assessment

Get a personalized demo

Ready to see Wiz in action?

"Best User Experience I have ever seen, provides full visibility to cloud workloads."
David EstlickCISO
"Wiz provides a single pane of glass to see what is going on in our cloud environments."
Adam FletcherChief Security Officer
"We know that if Wiz identifies something as critical, it actually is."
Greg PoniatowskiHead of Threat and Vulnerability Management