Timeline Block <= 1.3.3 - Insecure Direct Object Reference to Authenticated (Author+) Private Timeline Exposure via Shortcode Attribute
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:NTechnical Details
<=1.3.3Source Code
WordPress.org SVNThis 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)
- Entry Point: A user views a post or page containing the shortcode:
[timeline_block id="123"]. - Hook Registration: The plugin registers the shortcode via
add_shortcode('timeline_block', 'tlgb_shortcode'). - Processing: The
tlgb_shortcode($atts)function is called. - Data Retrieval: The function extracts the
idfrom$atts. It likely usesget_post($id)or aWP_Queryto fetch the timeline data. - 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'; } - 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:
- Identify the script localization variable (likely containing
ajax_url). - Use
wp post createto place the[timeline_block]shortcode on a page. - Navigate to that page using
browser_navigate. - Use
browser_evalto extract any nonces:window.tlgb_vars?.nonce.
- Identify the script localization variable (likely containing
- 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.
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.
- Create a timeline post of type
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_requesttool.
Payload:
[timeline_block id="[ID_OF_PRIVATE_TIMELINE]"]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
- 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" - Attacker Account:
wp user create attacker attacker@example.com --role=author --user_pass=password123
7. Expected Results
- Success: The
http_requestresponse for the Author's post containsSECRET_DATA_CONTENT_EXPOSED. - Failure: The response contains an error message, empty timeline, or redirects to a 404/Login page.
8. Verification Steps
- Confirm Post Privacy:
wp post get [PRIVATE_ID] --field=post_status # Should return 'private' - Check Ownership:
wp post get [PRIVATE_ID] --field=post_author # Should be the Admin ID, not the Author ID - 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=draftorpost_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 theidparameter. - AJAX Exposure: If the shortcode is just a wrapper, look for
wp_ajax_tlgb_get_timelinein the source code and attempt to call it directly with the private ID.
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
@@ -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.