Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Log in
Submit
ToolsExploitsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

FeedsContactPrivacy© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
Tools/GitHubGitHub/rootdirective-sec/cve-2026-27541-analysis-lab
Vulnerability AnalysisExploitationWeb Application ExploitationWeb SecurityPenetration TestingLearning & EducationLabs & Practice
GitHubrootdirective-sec/cve-2026-27541-analysis-lab

CVE-2026-27541-Analysis-Lab

Docker lab for reproducing CVE-2026-27541, an authenticated privilege escalation in WooCommerce Wholesale Prices. Compares vulnerable and patched builds, includes PoC script and root cause analysis.

View Repository
196 months agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

CVE-2026-27541 — WooCommerce Wholesale Prices Authenticated Privilege Escalation Lab

vulnx

Overview

This project is a local Docker lab for analyzing and reproducing the behavior of CVE-2026-27541 in the WooCommerce Wholesale Prices / Wholesale Suite plugin by comparing vulnerable and patched builds side-by-side on the same machine.

The core issue is Broken Access Control in the following REST API endpoint:

/wp-json/wwp/v1/admin/save

Based on the source code used in this lab, that route already has a permission_callback in both the vulnerable and patched builds. However, the affected version uses a capability check that is too broad for an admin settings write action:

  • vulnerable (2.2.6) → current_user_can( 'manage_woocommerce' )
  • patched (2.2.7) → current_user_can( 'manage_options' )

In this lab, the user shopmgr, which has the shop_manager role, has manage_woocommerce=true but not manage_options. As a result, this low-privilege user can use a valid logged-in session plus a valid X-WP-Nonce to invoke the admin settings save endpoint on the vulnerable build, while the patched build returns 403 rest_forbidden for the same request.


What this lab proves

  • Vulnerable node (2.2.6): the user shopmgr can successfully call POST /wp-json/wwp/v1/admin/save and modify plugin settings.
  • Patched node (2.2.7): the same request from shopmgr is rejected with 403.
  • No-auth request: if the endpoint is called directly without authentication, both builds return 403, which is consistent with this being a post-authentication privilege escalation issue.
  • Persistence proof: after a successful PoC run, the vulnerable build stores the WordPress option wwp_see_wholesale_prices_replacement_text=PWNED_BY_POC, while the patched build still returns See wholesale prices.

Lab Topology

Services

  • vuln → WordPress + WooCommerce + WooCommerce Wholesale Prices 2.2.6
  • patched → WordPress + WooCommerce + WooCommerce Wholesale Prices 2.2.7
  • db-vuln / db-patched → separate MariaDB databases
  • seed-vuln / seed-patched → wp-cli seed jobs that install WordPress, install the plugin, create users, and create a product for testing

Published ports

  • http://localhost:8081 → vulnerable
  • http://localhost:8082 → patched

Base images

  • WordPress: wordpress:6.8.1-php8.2-apache
  • MariaDB: mariadb:11.4.5
  • Seeder: wordpress:cli-php8.2

Repository Layout

.
├── docker-compose.yml
├── README.md
├── patched/
│   └── Dockerfile
├── vuln/
│   └── Dockerfile
├── scripts/
│   └── seed-wp.sh
└── poc.py

Important files

  • docker-compose.yml — defines the vulnerable and patched stacks with separate databases
  • scripts/seed-wp.sh — installs WordPress, WooCommerce, the target plugin, and creates test users and product data
  • poc.py — least-harm PoC for login, nonce extraction, and REST endpoint invocation

Seeded Environment

Once the stack is ready, the seed script creates the following:

Users

  • admin / AdminPass!234
  • shopmgr / ShopMgrPass!234

Product

  • slug: lab-product
  • regular price: 100
  • wholesale price: 50

Versions

  • WooCommerce: 10.6.0

  • WooCommerce Wholesale Prices:

    • vulnerable: 2.2.6
    • patched: 2.2.7

The script also writes lab-secrets.json into each WordPress container so the seeded data and version information can be verified.


Why the PoC is least-harm

This PoC does not attempt to take over the site, change roles, install plugins, or execute a shell.

It only does the following:

  1. logs in as shopmgr
  2. visits the relevant admin page to extract wpApiSettings.nonce
  3. sends a request to the target endpoint
  4. changes an easily observable setting value:
wwp_see_wholesale_prices_replacement_text = PWNED_BY_POC

This setting is used as an observable marker to demonstrate that a low-privilege user can modify admin-only configuration.


Vulnerability Summary

Affected component

  • Plugin: WooCommerce Wholesale Prices / Wholesale Suite
  • Route: POST /wp-json/wwp/v1/admin/save

Vulnerability class

  • Broken Access Control
  • Authenticated Privilege Escalation

Practical meaning

Although the endpoint requires a valid session and nonce, the vulnerable version still allows a low-privilege user such as shopmgr with the shop_manager role to invoke an endpoint that should be admin-only.

Important nuance

This is not an unauthenticated vulnerability.

If the endpoint is called directly without a logged-in session, both the vulnerable and patched builds reject the request. The bug exists in authorization after authentication, not in authentication itself.


Root Cause Analysis

The vulnerable version is not missing a permission_callback. The flaw is that it uses a capability check that is too broad (manage_woocommerce) for a REST action that writes admin-side settings.

From the source code in includes/class-wwp-admin-settings.php:

  • both the vulnerable and patched builds register the same route: POST /wp-json/wwp/v1/admin/save
  • both builds route it to save_registered_settings()
  • both builds use permission_admin_check() as the permission_callback
  • the real difference is the capability being checked

Vulnerable (2.2.6)

if ( ! current_user_can( 'manage_woocommerce' ) ) {
    return new WP_Error( 'rest_forbidden', ... );
}

Patched (2.2.7)

if ( ! current_user_can( 'manage_options' ) ) {
    return new WP_Error( 'rest_forbidden', ... );
}

In this lab, the user shopmgr, which has the shop_manager role, has manage_woocommerce=true but not manage_options, so it passes the vulnerable check but fails the patched one.

What changed in patched behavior

The patched version does more than change the response from 200 to 403. It changes the access-control logic by tightening the capability requirement from manage_woocommerce to manage_options.

In addition, the save path in the patched build is further hardened by moving away from prefix-based filtering toward explicit allowlists and stronger sanitization.

Why the PoC succeeds on vulnerable

The PoC follows the same flow as a real browser context:

  • log in as shopmgr
  • open the plugin settings page
  • extract wpApiSettings.nonce
  • call POST /wp-json/wwp/v1/admin/save

Because the vulnerable build allows users with manage_woocommerce to invoke this settings write action, the request succeeds and results in a persistent option change.

Security lesson

A nonce helps protect against CSRF, but it is not an authorization control.

Having a valid session and a valid nonce does not mean a user should be allowed to perform an admin action. Using an overly broad capability on a privileged endpoint is enough to create a low-privilege authorization bypass.


Reproducing the Lab

Prerequisites

  • Docker Desktop / Docker Engine
  • Docker Compose v2
  • Python 3
  • Internet access for the initial image and plugin downloads

1) Start the lab

docker compose up -d --build

2) Confirm containers are up

docker compose ps

You should see at least:

  • cve-2026-27541-vuln-1
  • cve-2026-27541-patched-1
  • cve-2026-27541-db-vuln-1
  • cve-2026-27541-db-patched-1

3) Watch the seeding logs

docker compose logs -f seed-vuln seed-patched

4) Inspect seeded metadata

docker compose exec vuln cat /var/www/html/lab-secrets.json
docker compose exec patched cat /var/www/html/lab-secrets.json

PoC Walkthrough

poc.py works as follows:

  1. GET /wp-login.php
Download Tool