One GET request and your mail credentials are gone: CVE-2026-4020 in Gravity SMTP
One GET request and your mail credentials are gone: CVE-2026-4020 in Gravity SMTP
You installed an SMTP plugin for WordPress, connected SendGrid or Amazon SES, confirmed that emails were going out — and moved on. The plugin works, everything is fine. Meanwhile, anyone on the internet, no account required, sends a single HTTP GET request and receives 365 KB of JSON containing your API keys, OAuth tokens, DKIM configuration, a full list of every installed plugin with version numbers, and your database structure. No login. No brute force. No exploit. Just a request to an open endpoint.
This is exactly what’s happening to sites running Gravity SMTP version 2.1.4 and below. The vulnerability is tracked as CVE-2026-4020, CVSS 7.5 (High), CWE-200 — Exposure of Sensitive Information to an Unauthorized Actor. Behind that score is a complete credential dump of your mail service, ready to use without any further preparation. Wordfence has already blocked more than 17 million exploitation attempts.
WHAT IS GRAVITY SMTP
Gravity SMTP is a commercial WordPress plugin from RocketGenius — the same team behind Gravity Forms. It solves a common problem: WordPress sends email through PHP’s mail() function by default, which fails on most hosting environments. Emails either don’t arrive at all or land in spam because the server isn’t authorized to send on behalf of the domain. Gravity SMTP replaces that broken mechanism with a connection to a professional mail service — SendGrid, Mailgun, Amazon SES, Google Workspace, Brevo, Postmark, Resend, Zoho, and others. The plugin is installed on approximately 100,000 sites.
That’s exactly what makes it an attractive target. An SMTP plugin is, by its nature, a credential store. It knows everything needed to send email on behalf of your domain: API keys, OAuth tokens, SMTP logins and passwords, DKIM configuration. Without those credentials the plugin can’t function, so they’re stored directly in WordPress — in the database and in the plugin configuration. That’s normal architecture; every SMTP plugin works this way.
HOW THE BUG WORKS
When a WordPress plugin registers a REST API endpoint, it must provide a permission_callback — a gatekeeper function that decides whether to pass a request through or reject it. Return true and the caller gets in. Return false and they get a 401. The entire access control model rests on this one function.
In Gravity SMTP, someone wrote a gatekeeper that lets everyone through. No exceptions. The endpoint /wp-json/gravitysmtp/v1/tests/mock-data is registered with a permission_callback that unconditionally returns true — no session check, no role check, no nonce, nothing. Append the query parameter ?page=gravitysmtp-settings and the plugin dutifully calls its internal register_connector_data() method, assembles a full System Report, and hands it back in the response. Everything the plugin knows about the system — on a plate.
The exploit is a single curl command. No special tools, no reconnaissance needed:
curl "https://example.com/wp-json/gravitysmtp/v1/tests/mock-data?page=gravitysmtp-settings"
The response is roughly 365 KB of JSON containing API keys and OAuth tokens for every configured mail integration, SMTP logins and passwords, DKIM tokens, PHP version, web server version, a full list of installed plugins with versions, the active theme, database table names, and the MariaDB/MySQL version.
All versions of Gravity SMTP through 2.1.4 are affected. The fix shipped in version 2.1.5 on March 17, 2026, before public disclosure. The patch added a proper access control check to the permission_callback.
TIMELINE
RocketGenius fixed the vulnerability in March 2026 — quietly, one line of code, no mention in the changelog, no email to users. The logic is understandable: don’t draw attention before most sites have updated. But paid plugins often have auto-updates disabled — administrators are worried an update will break their production customizations. The result: thousands of sites stayed on 2.1.4 with no idea a patch even existed.
In early May, administrators on r/WordPress started noticing something strange: SendGrid accounts suspended for spam, Mailgun bills tripling overnight, some providers silently rotating keys flagged as suspicious. CrowdSec recorded the first real-world exploitation on May 27 and by June 1 had classified the traffic as background noise — meaning the vulnerability had been absorbed into automated scanners sweeping WordPress sites continuously, without human involvement.
Wordfence published the official advisory on June 19, 2026. By that day the blocked-attempts counter had passed 17 million. The peak was June 7: over 4 million requests in a single day. The three months between the patch and public disclosure turned out not to be protection — they were a head start for whoever found the bug before Wordfence did.
WHY IT MATTERS
Two sites lost their SendGrid accounts. Both ran Gravity SMTP, both had paid SendGrid plans wired up for transactional email. Within 36 hours of their endpoint handing credentials to a scanner, SendGrid suspended both accounts for outbound spam. Recovery took eight days and required a written incident report. Eight days without transactional email — no order confirmations, no password reset emails, no notifications. For an online store that’s not a “security incident,” it’s an operational collapse.
CVSS 7.5 is High, and it’s earned: the attack requires nothing, zero prerequisites, zero privileges, one request. But what an attacker gets back isn’t just “information disclosure” in the abstract — it’s a ready-made toolkit for several independent attack vectors simultaneously.
A compromised SendGrid or Mailgun API key means an attacker can send email from your domain. Not spoofed — genuine, through your account, with your credentials. Those emails pass SPF checks because they’re sent through an authorized service. They pass DKIM checks because they’re signed with your key. From the perspective of every spam filter and every recipient, it’s legitimate email from your domain. Phishing groups pay serious money to rent infrastructure like this. Here it’s free, one curl request away.
At the same time, the attacker gets a complete map of your site. A list of installed plugins with exact version numbers is a basis for choosing the next attack vector. Got an outdated plugin with a known CVE? The attacker sees it immediately. PHP version, MariaDB version, database table names — all of it lowers the barrier for exploiting any other vulnerability the attacker finds or already has in their toolkit.
DKIM deserves its own paragraph. Most administrators reset API keys after an incident and consider the problem solved. But if DKIM tokens were in the dump, rotating API keys alone doesn’t close the gap. A DKIM key is tied to a DNS record on your domain, not to an account at the mail provider. If an attacker copied the private DKIM key, they can technically keep signing email with your domain’s signature — even after you’ve revoked every API key. The fix is DKIM selector rotation: generate a new key pair, create a new DNS TXT record, and deactivate the old selector at the provider.
WHAT TO DO
First, check whether the plugin is installed and what version is running. In the WordPress admin panel it’s visible under Plugins → Installed Plugins. Through WP-CLI it takes a second:
wp plugin get gravity-smtp --field=version
If the version is 2.1.4 or lower, update immediately:
wp plugin update gravity-smtp
After updating, confirm the patch is live. A request to the endpoint should now return 401 or 403, not a JSON payload:
curl -o /dev/null -s -w "%{http_code}" \
"https://example.com/wp-json/gravitysmtp/v1/tests/mock-data?page=gravitysmtp-settings"
If the site was running a vulnerable version, treat all credentials as compromised — whether or not you find traces of an attack in your logs. Attackers leave no trace in WordPress itself; they make a GET request to an open endpoint and get what they came for. The only evidence is in your web server access logs. Search them for requests to the vulnerable endpoint going back to May, when active scanning began:
grep "gravitysmtp/v1/tests/mock-data" /var/log/nginx/access.log
# or for Apache:
grep "gravitysmtp/v1/tests/mock-data" /var/log/apache2/access.log
If you see hits, the site was almost certainly scanned. The date of the first entry tells you when to start counting credentials as compromised. Rotate every API key configured in Gravity SMTP’s mail connectors — SendGrid, Mailgun, Amazon SES, Google OAuth, Brevo, anything that was connected. If DKIM was configured, generate a new selector at the provider, update the DNS TXT record, and deactivate the old selector. Rotating the API key without rotating the DKIM selector leaves the attacker able to keep signing mail with your domain.
While you’re at it, enable auto-updates. WordPress can automatically update plugins, but paid plugins often have this turned off — administrators worry an update will break their customizations. That fear is understandable, but the cost is exactly this kind of situation, where a patch sits for three months while the site stays vulnerable. Enable auto-updates via WP-CLI:
wp plugin auto-updates enable gravity-smtp
Or for all plugins at once, so you don’t have to decide which ones matter:
wp plugin auto-updates enable --all
If updating isn’t possible right now — for instance, the site is managed by a third party and requires sign-off — block the endpoint at the nginx level as a temporary measure:
location ~* /wp-json/gravitysmtp/ {
deny all;
return 403;
}
CONCLUSIONS
CVE-2026-4020 is a textbook CWE-200: one line of code in a permission_callback turns an SMTP plugin into a public credential dump. CVSS 7.5 (High), active exploitation, 17 million blocked attempts — all for a vulnerability that doesn’t even need to be “exploited” in the conventional sense. Access to an SMTP account with a clean sending reputation is worth more on the black market than many RCE exploits.
If Gravity SMTP is installed — update to 2.1.5, check your logs, rotate credentials and DKIM. If it isn’t installed — make sure your SMTP plugin isn’t registering public endpoints that return sensitive data. This applies to any plugin that stores API keys: from SMTP integrations to payment providers and CRM systems. The WordPress REST API is a convenient tool, but every unprotected endpoint is a potential leak.
The patch shipped in March. Sites are getting hit in June. That three-month gap isn’t the developer’s fault — they fixed the bug. It’s the cost of a silent patch with no notifications and auto-updates turned off. Next time it’ll be a different plugin, a different endpoint, the same outcome. The only thing that changes the equation is having auto-updates on, or actively tracking security releases for any plugin that holds your keys.
