CVE-2026-1870

Thim Kit for Elementor <= 1.3.7 - Missing Authorization to Unauthenticated Private Course Disclosure

mediumMissing Authorization
5.3
CVSS Score
5.3
CVSS Score
medium
Severity
1.3.8
Patched in
1d
Time to patch

Description

The Thim Kit for Elementor – Pre-built Templates & Widgets for Elementor plugin for WordPress is vulnerable to unauthorized access of data due to a missing validation checks on the 'thim-ekit/archive-course/get-courses' REST endpoint callback function in all versions up to, and including, 1.3.7. This makes it possible for unauthenticated attackers to disclose private or draft LearnPress course content by supplying post_status in the params_url payload.

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<=1.3.7
PublishedMarch 14, 2026
Last updatedMarch 14, 2026
Affected pluginthim-elementor-kit

What Changed in the Fix

Changes introduced in v1.3.8

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

# Exploitation Research Plan: CVE-2026-1870 (Thim Kit for Elementor) ## 1. Vulnerability Summary The **Thim Kit for Elementor** plugin (up to 1.3.7) contains a missing authorization vulnerability in its REST API implementation. Specifically, the endpoint `thim-ekit/archive-course/get-courses` (like…

Show full research plan

Exploitation Research Plan: CVE-2026-1870 (Thim Kit for Elementor)

1. Vulnerability Summary

The Thim Kit for Elementor plugin (up to 1.3.7) contains a missing authorization vulnerability in its REST API implementation. Specifically, the endpoint thim-ekit/archive-course/get-courses (likely under the thim-ekit/v1 namespace) fails to validate the post_status parameter within the params_url input. This allows unauthenticated users to query the database for courses with statuses that should be restricted, such as private, draft, or pending, leading to unauthorized disclosure of course content.

2. Attack Vector Analysis

  • Endpoint: /wp-json/thim-ekit/v1/archive-course/get-courses (Namespace v1 is inferred based on standard WordPress practices; thim-ekit is the identified base).
  • HTTP Method: GET (Primary) or POST.
  • Vulnerable Parameter: params_url.
  • Payload Key: post_status (inside params_url).
  • Authentication: Unauthenticated (None required).
  • Precondition: The LearnPress plugin must be installed and active, as this plugin specifically targets LearnPress course types (lp_course).

3. Code Flow (Inferred)

  1. Registration: The plugin registers a REST route thim-ekit/archive-course/get-courses via register_rest_route.
  2. Permission Callback: The permission_callback for this route is likely set to __return_true or lacks a check for is_user_logged_in().
  3. Data Processing: The callback function accepts a WP_REST_Request object.
  4. Parameter Extraction: It extracts the params_url parameter. If params_url is a string, it might use parse_str() to convert it into an array; if it is an array, it uses it directly.
  5. Query Building: The extracted parameters are passed into an array for WP_Query or a LearnPress-specific course query class.
  6. Sink: Because the plugin does not filter out or override the post_status key from the user-provided params_url, the attacker can set post_status to private or draft.
  7. Response: The database returns the matching courses, and the REST API returns their data (title, content, metadata) to the unauthenticated requester.

4. Nonce Acquisition Strategy

The vulnerability description explicitly states "unauthenticated attackers," suggesting that no nonce is required for the REST endpoint.

However, if a REST nonce is required for the v1 namespace, it can typically be found in the frontend source where Thim Kit widgets are active.

  1. Shortcode Identification: Look for Thim Kit archive widgets. Inferred shortcode: [thim-ekit-archive-course].
  2. Page Creation:
    wp post create --post_type=page --post_status=publish --post_title="Course Archive" --post_content='[thim-ekit-archive-course]'
  3. Extraction:
    Navigate to the page and use browser_eval to check for localized data:
    • browser_eval("window.thim_ekit_archive_course?.nonce")
    • browser_eval("window.thim_ekit?.rest_nonce")

Note: If the endpoint is truly unauthenticated and meant for AJAX-style loading of courses, a nonce is unlikely to be enforced.

5. Exploitation Strategy

The exploit involves sending a request to the REST API with a crafted params_url that includes post_status=private.

Request 1: Discovery (Testing if endpoint exists)

  • Tool: http_request
  • Method: GET
  • URL: /wp-json/thim-ekit/v1/archive-course/get-courses
  • Expected: A 200 OK or 400 Bad Request (missing params), but not a 404.

Request 2: Exploitation (Private Course Disclosure)

  • Tool: http_request
  • Method: GET
  • URL: /wp-json/thim-ekit/v1/archive-course/get-courses?params_url=post_status%3Dprivate
  • Alternative URL (if array-based): /wp-json/thim-ekit/v1/archive-course/get-courses?params_url[post_status]=private
  • Headers: Content-Type: application/json

Request 3: Exploitation (Draft Course Disclosure)

  • Tool: http_request
  • Method: GET
  • URL: /wp-json/thim-ekit/v1/archive-course/get-courses?params_url=post_status%3Ddraft

6. Test Data Setup

  1. Install Dependencies:
    • Install and activate LearnPress.
  2. Create Target Content:
    • Create a Private Course:
      wp post create --post_type=lp_course --post_title="Top Secret Course" --post_status=private --post_content="The password is: ThimKitVulnerable2026"
    • Create a Draft Course:
      wp post create --post_type=lp_course --post_title="Unfinished Business" --post_status=draft --post_content="Draft content here."
  3. Verify Post IDs:
    wp post list --post_type=lp_course --post_status=any

7. Expected Results

  • Success: The REST API returns a JSON response containing the "Top Secret Course" and "Unfinished Business" data.
  • Data Structure: The response should contain an array of course objects. Look for the title and content (or rendered) fields in the JSON.
  • Access Control: A non-vulnerable version should return an empty list or only public courses, regardless of the post_status parameter.

8. Verification Steps

  1. Confirm Output: Check the body of the http_request response for the string "ThimKitVulnerable2026".
  2. Verify Auth Status: Ensure the http_request is sent without any session cookies or Authorization headers to confirm the "unauthenticated" nature of the flaw.
  3. CLI Comparison:
    wp post get <ID> --field=post_status
    Confirm the ID found in the REST response matches the post that is indeed private or draft.

9. Alternative Approaches

  • Namespace Variations: If v1 is incorrect, try thim-ekit/v2 or check /wp-json/ index to find the correct namespace.
  • Method Variation: If GET fails, try a POST request:
    {
      "params_url": "post_status=private"
    }
    
  • Nested Query: Try params_url[query][post_status]=private if the plugin uses a nested query builder.
  • LearnPress Query Params: Try adding post_type=lp_course explicitly to the params_url:
    ?params_url=post_status=private&post_type=lp_course

Check if your site is affected.

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