← Back to Feed CACHED · 2026-05-17 09:42:19 · cache_key CVE-2025-29912
CVE-2026-8135 · CWE-502 · Disclosed 2026-05-21

Concrete CMS 9

ASSESSED — NOISGATE V0.5
Vendor
Reassessed
Verdict:
01 · The Real Story

This is a land mine buried behind the front desk, not a bomb in the parking lot

CVE-2026-8135 is an insecure deserialization flaw in Concrete CMS ExpressEntryList that affects 9.5.0 and earlier and is fixed in 9.5.1. A user who already has enough Concrete privileges to add blocks can abuse the REST API's JSON handling to satisfy the _fromCIF === true gate, store a malicious serialized payload in the block's filterFields column, and get code execution when an administrator later views or edits that block.

The vendor's *technical* severity is fair for impact but too hot for patch triage across a large estate. The decisive reality check is the prerequisite stack: this is PR:H, requires a Concrete role that can add blocks, depends on a specific block path, and only becomes RCE after admin interaction with the poisoned block state. That's post-initial-access abuse with a narrower exposed population than a typical internet-reachable RCE.

"This is server-takeover code execution, but only after you already hold a privileged CMS seat."
02 · The Attack Path

4 steps from start to impact.

STEP 01

Obtain a privileged Concrete session

The attacker first needs a valid Concrete CMS account with enough rights to add blocks to an area. In practice this means a rogue admin, a compromised delegated web-team account, or a third-party agency account already trusted inside the CMS. Typical tooling here is stolen-session reuse or normal browser access rather than a standalone exploit kit.
Conditions required:
  • Authenticated access to the target Concrete CMS instance
  • Role permissions sufficient to add blocks to at least one area
Where this breaks in practice:
  • This is not unauthenticated remote exploitation
  • Many enterprises heavily restrict CMS admin access behind SSO, VPN, IP allowlists, or delegated workflows
  • If only a tiny central web team holds these rights, reachable population drops fast
Detection/coverage: Version scanners can identify <=9.5.0, but they cannot confirm exploitable role assignments. IAM, SSO, and Concrete audit logs are more useful than perimeter scanning here.
STEP 02

Poison ExpressEntryList via REST API

Using a browser, curl, or Burp Suite, the attacker submits block data through the REST API path so json_decode() turns the JSON string "true" into a PHP boolean and bypasses the intended _fromCIF safeguard. That lets them write attacker-controlled serialized data into the filterFields database column for the ExpressEntryList block.
Conditions required:
  • Target uses the vulnerable ExpressEntryList block controller
  • Attacker can reach the REST/API workflow used to save block configuration
Where this breaks in practice:
  • This is a product-specific bug path, not a generic CMS primitive
  • The attacker still needs the exact block workflow and parameter shape
  • Not every Concrete deployment uses Express features or this block type operationally
Detection/coverage: Web logs may show unusual block-save activity on admin/API routes, but commodity scanners usually stop at version detection. DB content inspection for suspicious serialized payloads in block configuration is the high-signal check.
STEP 03

Wait for an administrator to touch the booby-trapped block

The stored payload is not the finish line by itself; execution happens when an administrator views or edits the block data later. That dependency on admin workflow is why the issue is dangerous but not broadly automatable in the wild.
Conditions required:
  • An administrator later views or edits the poisoned block
Where this breaks in practice:
  • No user interaction in the CVSS sense, but there is still an operational trigger requirement
  • Dormant or rarely managed blocks may never execute
  • If content and platform admins are separated, the trigger window can be long
Detection/coverage: Admin-page access logs around the affected block and PHP/application error logs are the best places to correlate trigger time. External scanners have almost no coverage for this trigger condition.
STEP 04

Execute gadget chain as the web server user

When the payload is deserialized, the attacker lands server-side code execution in the PHP application context, typically as the web server account. Weaponization would likely use normal PHP object injection/gadget-chain techniques rather than a bespoke loader.
Conditions required:
  • A working gadget chain exists in the target runtime/application set
  • PHP execution context has access to filesystem secrets, DB credentials, or deployment artifacts
Where this breaks in practice:
  • Real post-exploit blast radius depends on containerization, read-only filesystems, SELinux/AppArmor, and secret handling
  • If the site is well isolated, the attacker may get app compromise without easy host breakout
Detection/coverage: EDR on the web host can catch child processes, shell spawning, or suspicious PHP behavior, but only after the trigger. Traditional network IDS is weak against this class.
03 · Intelligence Metadata

The supporting signals.

In-the-wild statusNo public evidence of active exploitation found in the sources reviewed; CISA ADP in the OpenCVE record marks exploitation as none.
KEV statusNot KEV-listed as of the current CISA KEV catalog review.
EPSS0.00232 (~0.232%) from the user-supplied intel, which is low and consistent with a niche, privilege-heavy path rather than a broadly weaponized internet bug.
Proof-of-concept availabilityNo authoritative public PoC repository surfaced in the reviewed sources. Public writeups describe the primitive, but I did not find a primary-source exploit release from the reporter or vendor.
Vendor scoringUser-supplied vendor baseline is HIGH 7.2 with CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H; the vendor's published CVE/release-note text also shows a CVSS v4.0 8.9 HIGH path, reflecting the same high impact but different scoring model.
Affected versionsConcrete CMS 9.5.0 and earlier are listed as affected in the CVE record.
Fixed versionUpgrade to 9.5.1. I found no authoritative distro backport advisory in the reviewed sources, so treat upstream 9.5.1 as the fixed target unless your package maintainer says otherwise.
Trigger mechanicsThe exploit chain is authenticated and stored: abuse REST API JSON parsing to satisfy _fromCIF === true, write a serialized payload into filterFields, then wait for an admin view/edit to trigger deserialization.
Scanning/exposure dataNo trustworthy internet-scale, version-precise exposure count was available from reviewed sources. Inference: banner-based Shodan/Censys discovery for Concrete CMS is likely noisy, and exploitability still depends on app role assignments plus use of the ExpressEntryList path.
Disclosure and creditDisclosed on 2026-05-21; credited to Nguyễn Văn Thiện via HackerOne report H1 3643372 in vendor-linked records.
04 · The Call

noisgate verdict.

Final Verdict
DOWNGRADED to MEDIUM (5.8/10)

The decisive downgrade factor is attacker position: this bug requires already-authenticated, high-privilege access inside Concrete CMS, not anonymous reachability from the internet. The impact is full server-side code execution, but the reachable population is narrowed by role assignment, feature usage, and a stored-trigger workflow that depends on later admin interaction.

HIGH Attack prerequisites and affected/fixed version range
MEDIUM Real-world prevalence of exploitable role/feature combinations across enterprise deployments

Why this verdict

  • Downgrade for PR:H: the attacker already needs a privileged Concrete CMS account with block-creation rights, which implies prior compromise, insider abuse, or risky delegated access.
  • Downgrade for narrow exposure: only deployments using the vulnerable ExpressEntryList path and allowing that role to configure blocks are meaningfully exposed.
  • Downgrade for trigger friction: the stored payload still needs a later admin view/edit event, so this is not a one-shot wormable RCE.
  • Keep at MEDIUM, not LOW: once triggered, the result is real server-side code execution in the web app context, which can expose secrets, data, and adjacent infrastructure.

Why not higher?

This is not an unauthenticated edge-service bug and not even a low-privileged authenticated bug. Requiring high privileges inside the CMS, plus a specific feature path, plus a later admin-trigger event compounds downward pressure on severity for enterprise patch scheduling.

Why not lower?

Calling it LOW would ignore the fact that successful exploitation crosses an important boundary: CMS admin misuse becomes server-side code execution. That materially increases blast radius beyond normal content-management abuse, especially on flat web stacks with accessible secrets and writable deployment paths.

05 · Compensating Control

What to do — in priority order.

  1. Tighten block-creation privileges — Restrict who can add or edit blocks, especially on internet-facing sites and agency-managed instances. For a MEDIUM verdict there is no mitigation SLA — go straight to the 365-day remediation window, but this is the single best compensating control while you work through patching.
  2. Review delegated admin accounts — Audit SSO groups, local Concrete accounts, and third-party agency users for anyone who can manage blocks or Express content. Remove stale access now; there is no mitigation SLA for MEDIUM, but this sharply cuts the only realistic attacker population before the vendor fix is applied within the 365-day remediation window.
  3. Inspect for suspicious serialized block state — Search block configuration data, especially filterFields associated with ExpressEntryList, for unexpected serialized payloads or anomalous admin/API edits. Use this as a hygiene and threat-hunting measure during the 365-day remediation window if you cannot patch immediately.
  4. Harden the PHP runtime boundary — Use least-privilege filesystem permissions, separate service accounts, and host/container controls so a web-app RCE has less room to pivot. Even without a mitigation SLA for MEDIUM, this reduces post-exploit blast radius while you complete remediation inside 365 days.
What doesn't work
  • Generic perimeter WAF rules won't reliably stop this because the exploit lives in authenticated application logic and stored block configuration, not a simple edge signature.
  • MFA alone helps prevent account takeover but does nothing against a malicious or already-authenticated privileged user.
  • Version-only vulnerability scans identify potentially affected hosts but do not tell you whether the exploitable role/feature combination exists on that site.
06 · Verification

Crowdsourced verification payload.

Run this on the target Concrete CMS host or a mounted application filesystem, not from a network scanner. Invoke it as bash verify_concrete_cve_2026_8135.sh /var/www/html (or your Concrete install root); no root is required, but the script needs read access to the app files and php in PATH if it falls back to the CLI version check.

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash
# verify_concrete_cve_2026_8135.sh
# Checks whether a local Concrete CMS installation appears vulnerable to CVE-2026-8135.
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN, 3=usage/runtime error

set -u

TARGET="${1:-}"
if [[ -z "$TARGET" ]]; then
  echo "Usage: $0 /path/to/concretecms"
  exit 3
fi

if [[ ! -d "$TARGET" ]]; then
  echo "UNKNOWN - target directory not found: $TARGET"
  exit 2
fi

version=""

# Try composer.lock first
if [[ -f "$TARGET/composer.lock" ]]; then
  version=$(php -r '
    $f=$argv[1];
    $j=json_decode(file_get_contents($f), true);
    if (!is_array($j)) exit(1);
    $pkgs=array_merge($j["packages"] ?? [], $j["packages-dev"] ?? []);
    foreach ($pkgs as $p) {
      if (($p["name"] ?? "") === "concretecms/core" || ($p["name"] ?? "") === "concretecms/concretecms") {
        echo $p["version"] ?? "";
        exit(0);
      }
    }
    exit(1);
  ' "$TARGET/composer.lock" 2>/dev/null)
fi

# Fallback to Concrete CLI if present
if [[ -z "$version" && -x "$TARGET/concrete/bin/concrete5" ]]; then
  version=$(php "$TARGET/concrete/bin/concrete5" --version 2>/dev/null | grep -Eo '[0-9]+\.[0-9]+\.[0-9]+' | head -n1)
fi

# Normalize leading v and Composer-style suffixes
version=$(echo "$version" | sed -E 's/^v//; s/^([0-9]+\.[0-9]+\.[0-9]+).*/\1/')

if [[ -z "$version" ]]; then
  echo "UNKNOWN - could not determine Concrete CMS version from composer.lock or CLI"
  exit 2
fi

verlte() {
  # returns true if $1 <= $2
  [[ "$(printf '%s\n%s\n' "$1" "$2" | sort -V | head -n1)" == "$1" ]]
}

verlt() {
  # returns true if $1 < $2
  [[ "$1" != "$2" ]] && verlte "$1" "$2"
}

if verlte "$version" "9.5.0"; then
  echo "VULNERABLE - Concrete CMS version $version is <= 9.5.0"
  exit 1
elif verlt "$version" "9999.9999.9999"; then
  echo "PATCHED - Concrete CMS version $version is > 9.5.0"
  exit 0
else
  echo "UNKNOWN - unparsable version state: $version"
  exit 2
fi
07 · Bottom Line

If you remember one thing.

TL;DR
Monday morning, treat this as a post-auth RCE with narrow reach, not as an emergency internet-edge fire. Inventory every Concrete CMS instance at <=9.5.0, identify which ones actually delegate block-management rights, and upgrade those systems to 9.5.1 through normal web-app change control. For a MEDIUM verdict there is no noisgate mitigation SLA — go straight to the 365-day remediation window; use compensating controls where needed, and complete the actual vendor upgrade inside the noisgate remediation SLA of ≤365 days.

Sources

  1. CVE.org record for CVE-2026-8135
  2. Concrete CMS 9.5.1 release notes
  3. Concrete CMS GitHub releases
  4. Concrete CMS security program page
  5. CISA Known Exploited Vulnerabilities catalog
  6. FIRST EPSS API documentation
  7. OpenCVE record for CVE-2026-8135
  8. PatchSiren debrief for CVE-2026-8135
Peer Review

What defenders are saying.

Submit a review attribution: handle + country only
0 flags selected · stored anonymously
Validation Results

Crowdsourced verification outputs.

Results submitted by users who ran the verification payload against their environment.