Balbooa Forms: unauthenticated PHP upload to RCE (CVE-2026-56291)
An unauthenticated attacker can upload executable files through affected Balbooa Forms installations and run code on the Joomla server. CISA lists this vulnerability as exploited.
Public CVE record · Vendor advisory or update instructions · Module source · Source and API bundle · CNA advisory
Patch title. Balbooa Forms Executable Upload Guard (balbooa-forms-executable-upload-guard in the registry). The original source snapshot preserves the source available for the historical report.
| Field | Value |
|---|---|
| Affected component and versions | Balbooa Forms 2.4.0 and earlier |
| Fixed release | 2.4.1 |
| Severity | Critical (CVSS 4.0, 10.0, CNA) · CISA KEV |
| Evidence status | Synthetic comparison only |
| Test environment | Synthetic HTTP fixture behind a single-node Eden 1.103.0 interlay |
| Tested Eden release and module | 1.103.0 · gabriel_balbooaup_v1 1.0.0 |
| Registry package | balbooa-forms-executable-upload-guard 1.0.0 |
| Tested at | 2026-11-14 UTC |
| First publicly published | 2026-11-14T16:39:20Z |
Result. The marked request reached the synthetic backend in the baseline. Both protected configurations returned HTTP 403 for that request and the backend counter did not change. The native module passed the benign probe.
Synthetic HTTP controls
Tier 1 — declarative policy. The recorded policy denies every method on the recorded fixture route and its descendants. This is a coarse rule: it also blocked the benign probe on the same route, which is the recorded false positive.
{
"version": 1,
"profile": "http-structure-v1",
"policy": {
"version": 1,
"rules": [
{
"scope": {
"methods": [],
"path": "/balbooa",
"descendants": true
},
"require": {
"kind": "deny"
}
}
]
}
}
Tier 2 — native Rust module. The shared rule scans the target and body for .php or phar: when the target contains jce, pagebuilder, or balbooa.
static MARKS: [&[u8]; 2] = [b".php", b"phar:"];
Implement the remediation
Vendor update. Update Balbooa Forms to 2.4.1 or a later supported release. Follow the vendor’s instructions to inspect the extension’s upload directories for unexpected executable files. Vendor instructions.
The published package uses registry name balbooa-forms-executable-upload-guard. Verify its own archive digest before import. Use the fixture API example to reproduce the recorded comparison. It covers the declaration, signed module activation, verification, revocation, and restoration.
Fixture and probes
The benign probe uploaded a form definition. The marked probe uploaded shell.php. The fixture incremented its marker when a PHP-named upload reached the handler.
Measured comparison (2026-11-14 UTC)
The values after each status are the observed increases in the fixture's effect counter.
| Probe | Baseline | Declarative policy | Native module |
|---|---|---|---|
| Benign clean upload | 200, 0 | 403, 0 | 200, 0 |
| Marked PHP upload | 200, 1 | 403, 0 | 403, 0 |
Test scope
The shared rule scans the target and body for .php or phar: when the target contains jce, pagebuilder, or balbooa. The fixture did not run Balbooa Forms or check its upload validation, storage configuration, or PHP execution.
Signed module authority
Import returned HTTP 201 with explicit activation required and signature verification deferred. Read-only inspection was refused (403) for the reader principal, admission of a tampered statement was rejected (400), and admission of an invalid signature was refused (403). The activation receipt reported the module serving on all 32 expected shards. After revocation the marked probe received HTTP 503 (fail-closed); re-approval and reactivation restored the refusal (403, counter unchanged).
- Source SHA-256
b25e9817524d8b5f9eea548c8b98fc2437ae78e04cb764bf6f02e56e33e015e2 - Tested binary SHA-256
dfb739c9879670e0991df1f1393796eb447b2244dd198b7b4c0ecd397a723cf0 - Activation operation
836ec300-e469-4793-a93c-c93953850a13
Performance
Instrument: client wall-clock through the interlay (includes the network hop), warmup discarded, mean/p50/p95 in milliseconds.
| Arm | n | mean | p50 | p95 |
|---|---|---|---|---|
| Tier 1 — declarative policy, blocked | 15 | 0.4 ms | 0.4 ms | 0.6 ms |
| Tier 2 — module, benign passes (200) | 20 | 0.7 ms | 0.7 ms | 0.9 ms |
| Tier 2 — module, attack refused | 15 | 0.6 ms | 0.6 ms | 0.6 ms |