---
title: "WordPress SSRF Vulnerability Found in LiteSpeed Cache Plugin"
slug: "wordpress-ssrf-vulnerability-litespeed-cache-cve-2026-84761"
description: "A WordPress SSRF vulnerability in LiteSpeed Cache (CVE-2026-84761) and a firewall plugin exposed internal network requests. Patch details here."
date: 2026-09-18
author: "WP Vanguard Team"
category: "Education"
tags: ["wordpress-ssrf-vulnerability", "cve-2026-84761", "cve-2026-81806", "litespeed-cache", "server-side-request-forgery"]
featured_image: "/images/blog/wordpress-ssrf-vulnerability-litespeed-cache-cve-2026-84761.jpg"
---

On September 1, 2026, LiteSpeed shipped version 7.9.1 of LiteSpeed Cache to close CVE-2026-84761, a server-side request forgery bug carrying a CVSS score of 7.2. Days later, Hide My WP Ghost, a plugin whose entire job is site security and firewalling, patched its own unauthenticated SSRF flaw, CVE-2026-81806, also scored 7.2. Two SSRF bugs in two very different plugins, disclosed a week apart, is reason enough for our first post on what a WordPress SSRF vulnerability actually lets an attacker do.

Both bugs let an unauthenticated visitor make the web server send outbound requests somewhere the attacker chose, not the site owner. Neither report names the exact code path that triggers the request. We're not going to guess at internals nobody has published. What we can do is walk through the mechanics of SSRF in general, lay out exactly what's confirmed about each CVE, and give you a concrete way to write outbound requests in WordPress that don't have this problem.

## What SSRF actually lets an attacker do

Server-side request forgery means the server, not the attacker's browser, is the one making the network request. The attacker supplies a target, directly or indirectly, and the vulnerable code fetches it on their behalf. That sounds abstract until you think about what the server can reach that a random visitor on the internet cannot.

Most WordPress hosts run behind a private network boundary. Inside that boundary sit things the public internet was never meant to touch: cloud instance metadata endpoints (the classic one is `169.254.169.254`, which on AWS and similar platforms can hand back temporary credentials for whatever role the instance runs under), internal admin panels that assume only trusted machines can reach them, and services bound to localhost that were never given a password because nothing external was supposed to talk to them. Redis and Elasticsearch are the usual suspects.

An attacker who can point the server's own HTTP client at any of these has effectively borrowed the server's network position. They didn't compromise the machine. They just asked it to fetch something on their behalf, and it did.

There's a meaningful difference between blind SSRF and full-response SSRF. Blind SSRF tells the attacker nothing back; they can infer things from timing or side effects, but the response body never reaches them. Full-response SSRF, which is what LiteSpeed's advisory describes, hands the entire response back to the attacker. If that response happens to be a metadata endpoint returning temporary cloud credentials, or an internal API dumping user records, the attacker now has that data directly. That's the more dangerous flavor of the bug.

## The LiteSpeed Cache SSRF (CVE-2026-84761)

LiteSpeed Cache runs on more than 7,000,000 WordPress sites, and headlines about a bug in a plugin that size tend to write themselves. This one deserves more care than that. The vendor's advisory is explicit that only sites meeting two conditions at once are exposed: the site is served through the QUIC.cloud CDN, and the origin server's "Use Client IP in Header" setting in LiteSpeed Web Server is set to No, meaning the real visitor IP is never restored from the CDN's forwarded headers.

Sites without that specific combination are not affected, according to the vendor. We're stating that plainly because "7 million installs" is the kind of number that gets repeated without the caveat attached, and the caveat is the whole story here.

Patchstack found the bug and alerted LiteSpeed on August 9, 2026. LiteSpeed released the fix in version 7.9.1 on September 1 and published its own advisory the next day. Versions up to and including 7.9 are vulnerable. The vendor's writeup describes the impact as an unauthenticated attacker being able to make the site issue server-side requests to internal or otherwise unreachable network locations, and get the full response back. It does not name the specific endpoint, parameter, or code path that triggers this behavior, and neither will we. Guessing at a mechanism the vendor chose not to publish helps nobody and risks spreading something wrong.

The qualifying condition is about how `REMOTE_ADDR` gets set when a CDN sits in front of the site. That's a well-known risk area, and we'll come back to why further down.

Even if your setup doesn't match those two conditions, LiteSpeed still recommends every site upgrade to 7.9.1 or later. That's reasonable. Configurations change, and a patched plugin costs you nothing.

## The Hide My WP Ghost SSRF (CVE-2026-81806)

Hide My WP Ghost bills itself as a security and firewall plugin, active on more than 100,000 sites. CVE-2026-81806 is an unauthenticated SSRF affecting versions up to and including 7.0.09, fixed in 7.0.10. The public record describes it plainly: an attacker can make the plugin issue web requests to arbitrary locations from the WordPress application itself, and use that to query and modify information from internal services.

The mechanism isn't public. Same rule applies as above: we're not filling that gap with a guess.

What stands out is the category of plugin this landed in. A firewall and hardening tool is the software a site owner installs specifically to reduce attack surface. Finding an unauthenticated request-forgery bug inside it is an uncomfortable reminder that "security plugin" describes the plugin's purpose, not a guarantee about its own code quality. Every plugin, including the ones whose job is defense, is still software that has to be patched.

## Comparing the two

| | LiteSpeed Cache | Hide My WP Ghost |
|---|---|---|
| CVE | CVE-2026-84761 | CVE-2026-81806 |
| CVSS | 7.2 | 7.2 |
| Active installs | 7,000,000+ | 100,000+ |
| Affected versions | Up to and including 7.9 | Up to and including 7.0.09 |
| Fixed in | 7.9.1 | 7.0.10 |
| Auth required | None | None |
| Configuration-dependent | Yes, QUIC.cloud + IP header setting | No stated precondition |
| Response returned to attacker | Full response | Query/modify internal services |
| Mechanism disclosed | No | No |

The install-count gap is large, but it's the "configuration-dependent" row that actually determines your exposure to the LiteSpeed bug. Hide My WP Ghost's flaw carries no stated precondition, which arguably makes it the simpler one to worry about even with a tenth of the install base.

## Why trusting the client IP behind a CDN is risky

We can't tell you the confirmed mechanism behind CVE-2026-84761. We can explain the general principle behind the vendor's stated condition, because it's a well-understood problem independent of this specific bug.

When a request passes through a CDN or reverse proxy, the web server's own view of "who sent this" (`REMOTE_ADDR` in PHP) reflects the proxy's IP address, not the visitor's. The real client IP arrives instead in a header the proxy adds, commonly `X-Forwarded-For`. If the origin server is configured to trust and restore that header, `REMOTE_ADDR` gets rewritten back to the real visitor. If it isn't, as LiteSpeed's advisory describes for the "Use Client IP in Header: No" case, any code that makes decisions based on `REMOTE_ADDR` is working from the proxy's identity, not the requester's.

That matters anywhere a plugin uses IP-based logic to decide who's trusted, who gets rate-limited, or what's allowed to happen next. Get that assumption wrong behind a CDN that isn't restoring the real IP, and the check stops meaning what its author intended.

It's not just header spoofing, either. DNS rebinding is the other classic way SSRF defenses get bypassed: a hostname resolves to a safe-looking address at validation time, then to an internal address by the time the actual request fires. That's why any allowlist check has to happen against the IP the request will actually hit, not just the hostname string.

## Writing safe outbound requests in WordPress

WordPress core gives you two families of HTTP functions, and the difference between them is the whole SSRF story for plugin developers.

```php
// Unsafe: fetches whatever URL the request supplies, no restriction
$url = $_POST['webhook_url'];
$response = wp_remote_get( $url );
```

`wp_remote_get()` will happily fetch any URL you hand it, including `http://169.254.169.254/` or `http://localhost:6379/`. If a user-supplied value ever reaches that function unchecked, you've built an SSRF endpoint whether you meant to or not.

```php
// Safer: wp_safe_remote_get() rejects local/private targets,
// plus an explicit allowlist of hosts we actually trust
$url  = $_POST['webhook_url'];
$host = wp_parse_url( $url, PHP_URL_HOST );

$allowed_hosts = [ 'api.example.com', 'hooks.example.org' ];

if ( ! in_array( $host, $allowed_hosts, true ) ) {
    wp_send_json_error( 'Host not permitted', 400 );
}

$response = wp_safe_remote_get( $url );
```

`wp_safe_remote_get()` and the rest of the `wp_safe_remote_*` family run the target URL through `wp_http_validate_url()`, which rejects requests aimed at local and private network ranges before the request ever fires. As of WordPress 7.1 that list includes loopback, the private ranges, and `169.254.0.0/16`, the link-local range cloud metadata services sit on. One catch: a plugin can mark a host as allowed through the `http_request_host_is_external` filter, so that protection is only as strong as the code hooked into it. Layering an explicit allowlist of hosts on top closes the rest, because "not a private IP" and "a host I actually meant to call" are different guarantees.

The rule for anyone building a plugin: never pass a user-supplied URL straight into `wp_remote_get()` or its relatives. If the plugin needs to call out to a URL a user configures, that's exactly where `wp_safe_remote_get()` plus a host allowlist belongs.

## What to do now

If you run LiteSpeed Cache, update to 7.9.1 or later. If you're specifically running behind QUIC.cloud, go check the "Use Client IP in Header" setting in LiteSpeed Web Server while you're in there, since that's the condition the vendor names as the exposure.

If you run Hide My WP Ghost, update to 7.0.10 or later. There's no configuration workaround published for that one; the patch is the fix.

If your hosting dashboard exposes outbound connection logs from the web server, take a look. SSRF exploitation often shows up as unusual outbound requests to internal IP ranges or to metadata addresses, and that's a pattern worth knowing what normal looks like for, before you need to spot abnormal.

If you write or maintain plugins, audit every `wp_remote_get()`, `wp_remote_post()`, and related call that takes any part of its target URL from request input, a settings field, or a webhook config. Each one is a candidate for `wp_safe_remote_get()` plus an allowlist.

At the host level, defense in depth still helps even after patching. AWS's IMDSv2 requires a session token for metadata requests, which blunts the simplest SSRF-to-credential-theft path. Egress filtering on the web server, restricting what internal addresses it can reach at all, closes the same door from a different angle.

WP Vanguard's surface scan checks the plugin versions it can detect from outside your site against our vulnerability database, so it flags an outdated LiteSpeed Cache or Hide My WP Ghost version whenever it can detect one.

For the wider set of ways sites get compromised, our rundown of [how WordPress sites actually get hacked](/blog/how-wordpress-sites-get-hacked) and our [WordPress security checklist](/blog/wordpress-security-checklist) cover the ground SSRF alone doesn't. We've also written about a [cache plugin RCE](/blog/breeze-cache-rce-cve-2026-3844) that shows a different way a caching layer can go wrong, and about what the [available vulnerability data actually says](/blog/is-wordpress-secure-vulnerability-data) about WordPress security overall. If you want an always-on view instead of a one-time check, see our list of [free WordPress security monitoring tools](/blog/free-wordpress-security-monitoring-tools).

Run a free scan at [wpvanguard.com](/#scanner) to see which plugin versions your site is exposing right now.

## References

- [LiteSpeed: Security Update for LSCWP - CVE-2026-84761](https://blog.litespeedtech.com/2026/09/02/security-update-for-lscwp-cve-2026-84761/)
- [NVD: CVE-2026-84761 Detail](https://nvd.nist.gov/vuln/detail/CVE-2026-84761)
- [NVD: CVE-2026-81806 Detail](https://nvd.nist.gov/vuln/detail/CVE-2026-81806)
- [OWASP: Server-Side Request Forgery](https://owasp.org/www-community/attacks/Server_Side_Request_Forgery)
- [WordPress Developer Reference: wp_safe_remote_get()](https://developer.wordpress.org/reference/functions/wp_safe_remote_get/)
