CVE-2026-1228

Timeline Block <= 1.3.3 - Insecure Direct Object Reference to Authenticated (Author+) Private Timeline Exposure via Shortcode Attribute

mediumAuthorization Bypass Through User-Controlled Key
4.3
CVSS Score
4.3
CVSS Score
medium
Severity
1.3.4
Patched in
1d
Time to patch

Description

The Timeline Block – Beautiful Timeline Builder for WordPress (Vertical & Horizontal Timelines) plugin for WordPress is vulnerable to Insecure Direct Object Reference in all versions up to, and including, 1.3.3 via the tlgb_shortcode() function due to missing validation on a user controlled key. This makes it possible for authenticated attackers, with Author-level access and above, to disclose private timeline content via the id attribute supplied to the 'timeline_block' shortcode.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=1.3.3
PublishedFebruary 5, 2026
Last updatedFebruary 6, 2026
Affected plugintimeline-block-block

Source Code

WordPress.org SVN
Research Plan
Unverified

This research plan outlines the methodology for analyzing and exploiting **CVE-2026-1228**, an Insecure Direct Object Reference (IDOR) vulnerability in the **Timeline Block** WordPress plugin. ## 1. Vulnerability Summary The **Timeline Block** plugin (<= 1.3.3) fails to perform proper authorization…

Show full research plan

This research plan outlines the methodology for analyzing and exploiting CVE-2026-1228, an Insecure Direct Object Reference (IDOR) vulnerability in the Timeline Block WordPress plugin.

1. Vulnerability Summary

The Timeline Block plugin (<= 1.3.3) fails to perform proper authorization checks when rendering timeline content via its shortcode. Specifically, the tlgb_shortcode() function accepts an id attribute to specify which timeline post to display. Because the function does not verify if the current user has the authority to view the referenced post (e.g., if the post is marked as "Private" or "Draft"), an authenticated user with permission to use shortcodes (Author level and above) can disclose the contents of private timelines by referencing their post IDs.

2. Attack Vector Analysis

  • Shortcode Name: timeline_block (inferred from description)
  • Attribute: id
  • Vulnerable Function: tlgb_shortcode()
  • Required Authentication: Author level or higher (users who can create/edit posts and thus execute shortcodes).
  • Vulnerability Type: Authorization Bypass (IDOR).
  • Impact: Information disclosure of private timeline content.

3. Code Flow (Inferred)

  1. Entry Point: A user views a post or page containing the shortcode: [timeline_block id="123"].
  2. Hook Registration: The plugin registers the shortcode via add_shortcode('timeline_block', 'tlgb_shortcode').
  3. Processing: The tlgb_shortcode($atts) function is called.
  4. Data Retrieval: The function extracts the id from $atts. It likely uses get_post($id) or a WP_Query to fetch the timeline data.
  5. The Sink: The plugin fetches the post object regardless of its post_status. It lacks a check such as:
    $post = get_post($id);
    if ($post->post_status === 'private' && !current_user_can('read_post', $id)) {
        return 'Unauthorized';
    }
    
  6. Output: The private content is rendered into the HTML of the page being viewed by the attacker.

4. Nonce Acquisition Strategy

This vulnerability resides in a shortcode, which is processed server-side during page rendering.

  • Shortcode Rendering: Typically does not require a nonce. The "authorization" is implicitly granted by the user's ability to publish or preview a post containing the shortcode.
  • Potential AJAX: If the shortcode renders a container that then fetches data via AJAX:
    1. Identify the script localization variable (likely containing ajax_url).
    2. Use wp post create to place the [timeline_block] shortcode on a page.
    3. Navigate to that page using browser_navigate.
    4. Use browser_eval to extract any nonces: window.tlgb_vars?.nonce.
  • Current Assessment: Based on the "Private Timeline Exposure via Shortcode Attribute" description, the exposure occurs during the initial shortcode expansion. No nonce is likely required for the primary exploit.

5. Exploitation Strategy

The goal is to prove that an Author can view a "Private" timeline created by an Administrator.

  1. Setup Phase (Admin):

    • Create a timeline post of type timeline_block (inferred post type).
    • Set the content to a unique "Sensitive Secret String".
    • Set the post status to private.
    • Capture the ID of this private post.
  2. Execution Phase (Author):

    • Log in as a user with the Author role.
    • Create a new post containing the shortcode: [timeline_block id="PRIVATE_POST_ID"].
    • Publish or Preview the post.
    • Request the URL of the newly created post via the http_request tool.
  3. Payload:

    [timeline_block id="[ID_OF_PRIVATE_TIMELINE]"]
    
  4. Expected Response:

    • The HTTP response body should contain the "Sensitive Secret String" within the rendered timeline HTML, despite the post being private.

6. Test Data Setup

  1. Private Content (Admin):
    # Create the private timeline
    # Note: 'timeline_block' is the inferred post type; adjust if different
    PRIVATE_ID=$(wp post create --post_type=timeline_block --post_title="Private Timeline" --post_content="SECRET_DATA_CONTENT_EXPOSED" --post_status=private --porcelain)
    echo "Private Timeline ID: $PRIVATE_ID"
    
  2. Attacker Account:
    wp user create attacker attacker@example.com --role=author --user_pass=password123
    

7. Expected Results

  • Success: The http_request response for the Author's post contains SECRET_DATA_CONTENT_EXPOSED.
  • Failure: The response contains an error message, empty timeline, or redirects to a 404/Login page.

8. Verification Steps

  1. Confirm Post Privacy:
    wp post get [PRIVATE_ID] --field=post_status
    # Should return 'private'
    
  2. Check Ownership:
    wp post get [PRIVATE_ID] --field=post_author
    # Should be the Admin ID, not the Author ID
    
  3. Inspect Rendered HTML:
    Verify the HTML structure surrounding the leaked content matches the plugin's timeline output classes (e.g., tlgb-timeline-wrapper).

9. Alternative Approaches

  • Draft Exposure: Attempt to reference a post with post_status=draft or post_status=trash.
  • REST API Check: Check if the plugin registers any REST API endpoints for fetching timeline data (e.g., /wp-json/tlgb/v1/timeline/) that might also lack authorization checks on the id parameter.
  • AJAX Exposure: If the shortcode is just a wrapper, look for wp_ajax_tlgb_get_timeline in the source code and attempt to call it directly with the private ID.
Research Findings
Static analysis — not yet PoC-verified

Summary

The Timeline Block plugin for WordPress (up to version 1.3.3) fails to validate user permissions when rendering timelines via shortcodes. By using the 'timeline_block' shortcode with a specific 'id' attribute, an authenticated user with Author-level access can view the contents of private or draft timelines that they should not be able to access.

Vulnerable Code

// timeline-block-block/includes/shortcode-handler.php (inferred from analysis)
function tlgb_shortcode($atts) {
    $atts = shortcode_atts(array(
        'id' => '',
    ), $atts);

    if (empty($atts['id'])) {
        return '';
    }

    $post_id = intval($atts['id']);
    $post = get_post($post_id);

    if ($post && $post->post_type === 'timeline_block') {
        // Vulnerability: No check to ensure the post is public or that the user has permission to read it.
        return tlgb_render_timeline_content($post);
    }
    return '';
}

Security Fix

--- timeline-block-block/includes/shortcode-handler.php
+++ timeline-block-block/includes/shortcode-handler.php
@@ -10,7 +10,7 @@
     $post_id = intval($atts['id']);
     $post = get_post($post_id);
 
-    if ($post && $post->post_type === 'timeline_block') {
+    if ($post && $post->post_type === 'timeline_block' && ( 'publish' === $post->post_status || current_user_can( 'read_post', $post_id ) ) ) {
         return tlgb_render_timeline_content($post);
     }
     return '';

Exploit Outline

1. Gain access to a WordPress account with at least 'Author' privileges, which allows the creation or editing of posts and the use of shortcodes. 2. Identify the target post ID of a private timeline created by another user (e.g., an administrator). 3. Create a new post or page and insert the shortcode [timeline_block id='TARGET_ID'], replacing TARGET_ID with the private post's ID. 4. Preview or publish the post and navigate to its URL. 5. The rendered page will display the sensitive content of the private timeline, bypassing intended authorization controls.

Check if your site is affected.

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