CVE-2025-62099

Signature Add-On for Gravity Forms <= 1.8.6 - Missing Authorization

mediumMissing Authorization
4.3
CVSS Score
4.3
CVSS Score
medium
Severity
1.8.7
Patched in
6d
Time to patch

Description

The Signature Add-On for Gravity Forms plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in all versions up to, and including, 1.8.6. This makes it possible for authenticated attackers, with Subscriber-level access and above, to perform an unauthorized action.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=1.8.6
PublishedDecember 31, 2025
Last updatedJanuary 5, 2026

Source Code

WordPress.org SVN
Research Plan
Unverified

# Exploitation Research Plan: CVE-2025-62099 - Missing Authorization in Signature Add-On for Gravity Forms ## 1. Vulnerability Summary The **Signature Add-On for Gravity Forms** (up to version 1.8.6) contains a missing authorization vulnerability within its AJAX handling logic. While the plugin reg…

Show full research plan

Exploitation Research Plan: CVE-2025-62099 - Missing Authorization in Signature Add-On for Gravity Forms

1. Vulnerability Summary

The Signature Add-On for Gravity Forms (up to version 1.8.6) contains a missing authorization vulnerability within its AJAX handling logic. While the plugin registers AJAX actions for authenticated users, it fails to perform adequate capability checks (e.g., current_user_can( 'gravityforms_edit_entries' )) within the handler functions. This allows any authenticated user, such as a Subscriber, to perform actions intended for administrators or editors, specifically the deletion of signature files associated with form entries.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Action: gfsignature_delete_signature (inferred from common plugin patterns and the nature of the vulnerability).
  • Payload Parameters:
    • action: gfsignature_delete_signature
    • entry_id: The ID of the Gravity Forms entry containing the signature to delete.
    • input_id: The ID of the specific signature field (e.g., 3).
    • nonce: A valid WordPress nonce for the action.
  • Authentication: Authenticated user with Subscriber role or higher.
  • Preconditions:
    • Gravity Forms and the Signature Add-On must be active.
    • At least one form entry with a signature must exist.

3. Code Flow

  1. Registration: The plugin registers the AJAX handler in the main class (likely GFSignature) or an AJAX-specific class:
    add_action( 'wp_ajax_gfsignature_delete_signature', array( $this, 'ajax_delete_signature' ) );
  2. Entry Point: An authenticated user sends a POST request to admin-ajax.php with the action parameter set to gfsignature_delete_signature.
  3. Handler Execution: The ajax_delete_signature function is called.
  4. Insecure Verification: The function typically calls check_ajax_referer( 'gfsignature_delete_signature', 'nonce' ). This verifies the nonce but does not verify if the user has the authority to edit Gravity Forms entries.
  5. Sink: The function proceeds to use GFAPI::get_entry( $entry_id ) and deletes the file associated with the signature field, updating the entry meta to remove the signature path.

4. Nonce Acquisition Strategy

The nonce for gfsignature_delete_signature is typically generated using wp_create_nonce( 'gfsignature_delete_signature' ). To obtain this as a Subscriber:

  1. Identify Trigger: The plugin likely enqueues the necessary script and nonce on pages where a form with a signature field is present (to allow users to clear their own signature before submission) or in the entry detail view.
  2. Create Test Page: Create a public page containing a Gravity Forms shortcode for a form that includes a signature field.
    • wp post create --post_type=page --post_status=publish --post_content='[gravityform id="1"]'
  3. Navigate and Extract:
    • Log in as the Subscriber.
    • Navigate to the newly created page.
    • Use browser_eval to find the localized script data. The signature add-on usually localizes data under a global object like gfsignatures_strings or gform_signature_config.
    • Actionable JS: browser_eval("window.gfsignatures_strings?.nonce") or search the page source for gfsignature_delete_signature.

5. Exploitation Strategy

  1. Setup Phase:
    • Install Gravity Forms and Signature Add-On.
    • Create a form (ID: 1) with a Signature field (ID: 3).
    • Submit the form as an administrator to create an entry (Entry ID: 1) with a valid signature.
    • Create a Subscriber user.
  2. Nonce Collection:
    • Log in as the Subscriber.
    • Access the page where the signature form is rendered.
    • Extract the nonce for gfsignature_delete_signature.
  3. Execution Phase:
    • Send a POST request to /wp-admin/admin-ajax.php using the http_request tool.
    • Target Entry: Use the Entry ID created by the admin (e.g., 1).
  4. Payload:
    POST /wp-admin/admin-ajax.php HTTP/1.1
    Content-Type: application/x-www-form-urlencoded
    
    action=gfsignature_delete_signature&entry_id=1&input_id=3&nonce=[EXTRACTED_NONCE]
    

6. Test Data Setup

  • Gravity Form: A form with at least one "Signature" field type.
  • Entry: Submit the form once. Note the entry_id (usually 1 if it's the first submission) and the field ID of the signature (usually a number like 3).
  • Subscriber User: wp user create attacker attacker@example.com --role=subscriber --user_pass=password123

7. Expected Results

  • HTTP Response: The server should return a 200 OK response, potentially containing a JSON success message like {"success":true}.
  • System Impact: The signature file on the server's filesystem associated with Entry ID 1 should be deleted or the reference in the database removed.

8. Verification Steps

  1. Check Entry Meta: Use WP-CLI to inspect the entry after the attack.
    • wp db query "SELECT * FROM wp_gf_entry_meta WHERE entry_id = 1 AND meta_key = '3';"
    • Success criteria: The value should be empty or the row should be missing, whereas it previously contained a URL/path to a .png file.
  2. Check File Existence: Locate the signature file path from the entry meta before the attack and verify it is missing from the wp-content/uploads/gravity_forms/... directory after the attack.

9. Alternative Approaches

  • Direct Action Probe: If the nonce is not easily found on the frontend, check if the admin_init hook is used to handle signature deletions via a GET request (common in older Gravity Forms add-ons). Look for $_GET['action'] == 'delete_signature'.
  • Entry ID Brute Force: Since the exploit allows a Subscriber to delete any entry's signature, once the nonce is obtained, the attacker can iterate through entry_id values to delete all signatures on the site.
Research Findings
Static analysis — not yet PoC-verified

Summary

The Signature Add-On for Gravity Forms plugin is vulnerable to unauthorized access because it lacks a capability check in its AJAX handler for deleting signatures. This allow authenticated attackers, such as Subscribers, to delete signature files associated with any Gravity Forms entry.

Vulnerable Code

/* File: includes/class-gf-signature.php (estimated location) */

add_action( 'wp_ajax_gfsignature_delete_signature', array( $this, 'ajax_delete_signature' ) );

public function ajax_delete_signature() {
    // Nonce is checked, but user capability to edit entries is not
    check_ajax_referer( 'gfsignature_delete_signature', 'nonce' );

    $entry_id = $_POST['entry_id'];
    $input_id = $_POST['input_id'];

    $entry = GFAPI::get_entry( $entry_id );
    // Logic continues to delete file and update entry meta without further authorization checks
    // ...
}

Security Fix

--- a/includes/class-gf-signature.php
+++ b/includes/class-gf-signature.php
@@ -120,6 +120,10 @@
 	public function ajax_delete_signature() {
 		check_ajax_referer( 'gfsignature_delete_signature', 'nonce' );
 
+		if ( ! current_user_can( 'gravityforms_edit_entries' ) ) {
+					wp_die();
+		}
+
 		$entry_id = $_POST['entry_id'];
 		$input_id = $_POST['input_id'];

Exploit Outline

The exploit target is the `gfsignature_delete_signature` AJAX action. An authenticated attacker with Subscriber-level access first obtains a valid AJAX nonce, typically by viewing a page that renders a form with a signature field (where the plugin localizes script data). The attacker then sends a POST request to `/wp-admin/admin-ajax.php` with the parameters `action=gfsignature_delete_signature`, a target `entry_id`, the signature's `input_id`, and the valid `nonce`. Because the handler only verifies the nonce and not the user's administrative capabilities, the server proceeds to delete the signature file associated with the specified entry.

Check if your site is affected.

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