This is a cashier accepting a discontinued SKU because the barcode check happens too late
CVE-2025-22384 affects Optimizely Configured Commerce before 5.2.2408. The flaw is a business-logic bypass in the Commerce B2B storefront: by altering requests before they reach the server, a storefront visitor can sometimes push a discontinued product into the purchase workflow when the application should have blocked it. The issue is about server-side enforcement of product state, not memory corruption, auth bypass, or code execution.
Reality is well below the scary 7.5 label attached in CVE enrichment. Optimizely's own advisory for COM-2024-02 calls it CVSS 5.9 / Medium, and even that is still a bit generous for enterprise patch triage. The attack needs a very specific commerce condition, usually depends on a product that is still discoverable or referenceable, and the blast radius is mostly bad orders, fulfillment exceptions, and revenue/ops friction—not tenant takeover, data theft, or fleet compromise.
4 steps from start to impact.
Find a target SKU
Burp Suite or mitmproxy to identify a product identifier that was discontinued but is still referenceable somewhere in the storefront flow. That can come from stale catalog views, cached pages, prior carts, saved lists, or predictable item identifiers.- Internet or partner access to the storefront
- A discontinued product remains addressable by ID or cached workflow state
- The storefront exposes enough product metadata to build a purchase request
- Many teams remove discontinued items from browse/search quickly
- Some sites require customer login before pricing/cart actions
- SKU discovery is harder when product IDs are not obvious and caches expire fast
Tamper with the purchase request
Burp Repeater and alters parameters so the request still references the discontinued SKU before server-side validation occurs. The core weakness is trusting a client-controllable parameter or stale workflow state that should have been revalidated server-side.- Ability to modify HTTP requests in transit
- The vulnerable pre-5.2.2408 server-side workflow path is present
- No compensating custom validation in partner code or ERP middleware
- Reverse proxies, custom middleware, or partner extensions may already reject bad SKU state
- Modern storefront customizations often re-check availability during cart or ERP sync
- Some deployments disable guest purchase paths entirely
Server accepts the item into workflow
- The request lands on a vulnerable node before upgrade to 5.2.2408
- The specific purchase path does not revalidate product state
- Clustered environments may have custom order review hooks
- ERP or payment side checks can still break the order before fulfillment
- Business operations often manually review suspicious unavailable-item orders
Operational impact, not host compromise
- The order survives downstream validation long enough to create business impact
- Inventory, fulfillment, and finance systems often catch the problem downstream
- Impact is bounded to affected storefronts and order workflows, not the whole estate
submitted order events where the SKU is currently inactive/discontinued in PIM/ERP.The supporting signals.
| In-the-wild status | No public exploitation evidence located in reviewed sources, and not listed in CISA KEV. |
|---|---|
| Proof-of-concept availability | No public PoC repo found in reviewed results. Vendor wording says triggering it is 'not trivial', which fits a manual workflow-tampering issue more than a copy-paste exploit. |
| EPSS | 0.00368 (user-supplied), which is low for 30-day exploitation likelihood. Treat that as consistent with a niche business-logic flaw rather than an internet-wide attacker favorite. |
| KEV status | Not KEV-listed in the reviewed CISA catalog results. |
| CVSS scoring dispute | There is a material scoring mismatch: Optimizely advisory COM-2024-02 says CVSS 5.9 / Medium, while CISA-ADP enrichment in NVD shows 7.5 / High with AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N. That C:H rating does not match the published business impact. |
| Affected versions | All Configured Commerce versions before 5.2.2408; NVD CPE shows versions up to but excluding 5.2.2408. |
| Fixed version | 5.2.2408. Optimizely states the fix validates product status before entering the purchase workflow. |
| Exposure pattern | This is typically a public-facing B2B storefront issue, but reachable population is still narrower than CVSS implies because exploitation depends on catalog state, purchase flow design, and whether discontinued SKUs remain referenceable. |
| Scanner / telemetry coverage | Weak scanner coverage. This is not a banner-grab or package-signature problem; meaningful detection usually comes from manual DAST or business-event monitoring on orders containing discontinued items. |
| Timeline / attribution | Vendor advisory published December 13, 2024, CVE record created January 4, 2025, vendor article updated January 6, 2025, and NVD modified May 20, 2025. No individual researcher is named in the reviewed sources. |
noisgate verdict.
The decisive factor is impact compression: the flaw is internet-reachable, but it only abuses a narrow commerce workflow and usually ends in an invalid order, not system compromise. In real enterprises, downstream inventory, ERP, and manual order-review controls sharply reduce the practical blast radius.
Why this verdict
- Downgrade from vendor/CVE enrichment baseline: the published effect is buying discontinued products, not code execution, auth bypass, or broad data access; that knocks the score down hard.
- Attacker still needs a live business condition: a discontinued SKU must remain referenceable through a vulnerable workflow. That is a real prerequisite and narrows exposed population materially.
- Modern business controls absorb impact: ERP validation, fulfillment checks, and manual order review often stop or limit bad orders even if the web tier accepts them.
- No current threat pressure: low EPSS, no KEV, and no public PoC/exploitation evidence located means this is not where attackers are concentrating effort.
Why not higher?
Because nothing in the published record indicates host compromise, privilege gain, tenant escape, or meaningful confidentiality loss. The CVSS enrichment overweights generic network reachability and underweights the fact that this is a business-rule miss with constrained business impact.
Why not lower?
Because the storefront may be public, no prior compromise is required, and a real customer-facing workflow can be abused remotely. If your business handles controlled, regulated, or safety-sensitive products, a discontinued-item order can still create non-trivial operational and contractual fallout.
What to do — in priority order.
- Purge discontinued SKUs from customer-facing paths — Remove discontinued products from browse, search, saved-list reuse, and direct product references so attackers cannot easily recover SKU identifiers or stale workflow state. For a LOW verdict there is no SLA; treat this as backlog hygiene and complete it in the next normal commerce change window.
- Add downstream order-state validation — Enforce a second check in cart submission, ERP handoff, or order orchestration that rejects any SKU whose current lifecycle state is discontinued/inactive. For a LOW verdict there is no SLA; add it during standard engineering maintenance rather than emergency change.
- Alert on impossible orders — Create detections for orders containing SKUs flagged discontinued, retired, inactive, or unavailable in PIM/ERP so operations can cancel them before fulfillment. For a LOW verdict there is no SLA; implement as part of normal fraud/ops telemetry tuning.
- Require authentication for higher-risk purchase flows — If your storefront allows guest order actions, consider moving sensitive ordering paths behind customer authentication to reduce anonymous tampering and improve accountability. For a LOW verdict there is no SLA; evaluate in the regular product roadmap unless business risk is unusually high.
- A generic EDR/AV agent does not help; this is an application workflow issue, not malware on the host.
- A basic vulnerability scanner usually will not catch this because the flaw depends on business state and request tampering, not a static version banner alone.
- A signature-only WAF rule is weak here because the malicious request can look structurally normal; the problem is semantic product-state enforcement.
Crowdsourced verification payload.
Run this on the Windows IIS/app server hosting Optimizely Configured Commerce with local read access to the application directory; administrator is helpful but not strictly required if the app files are readable. Invoke it as powershell -ExecutionPolicy Bypass -File .\check-cve-2025-22384.ps1 -Root 'C:\inetpub\wwwroot\ConfiguredCommerce' and it will inspect assembly metadata and config text for a version at or above 5.2.2408.
# check-cve-2025-22384.ps1
# Defensive validation helper for CVE-2025-22384 / Optimizely Configured Commerce
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN, 3=ERROR
param(
[Parameter(Mandatory=$true)]
[string]$Root,
[string]$FixedVersion = '5.2.2408'
)
function Write-Result {
param(
[string]$State,
[string]$Message,
[int]$Code
)
Write-Output "$State - $Message"
exit $Code
}
function Normalize-VersionParts {
param([string]$Version)
if ([string]::IsNullOrWhiteSpace($Version)) { return $null }
$clean = ($Version -replace '[^0-9\.]', '')
if ([string]::IsNullOrWhiteSpace($clean)) { return $null }
$parts = $clean.Split('.') | Where-Object { $_ -ne '' }
if ($parts.Count -lt 3) { return $null }
$nums = @()
foreach ($p in $parts) {
try { $nums += [int]$p } catch { return $null }
}
return ,$nums
}
function Compare-Version {
param(
[string]$A,
[string]$B
)
$va = Normalize-VersionParts $A
$vb = Normalize-VersionParts $B
if ($null -eq $va -or $null -eq $vb) { return $null }
$max = [Math]::Max($va.Count, $vb.Count)
for ($i = 0; $i -lt $max; $i++) {
$ai = if ($i -lt $va.Count) { $va[$i] } else { 0 }
$bi = if ($i -lt $vb.Count) { $vb[$i] } else { 0 }
if ($ai -gt $bi) { return 1 }
if ($ai -lt $bi) { return -1 }
}
return 0
}
function Get-CandidateVersionStrings {
param([string]$Path)
$found = New-Object System.Collections.Generic.List[string]
# 1) Inspect DLL/EXE metadata for Optimizely/Insite-related assemblies
$bins = @(
(Join-Path $Path 'bin'),
(Join-Path $Path 'wwwroot\\bin')
) | Where-Object { Test-Path $_ }
foreach ($bin in $bins) {
Get-ChildItem -Path $bin -Recurse -Include *.dll,*.exe -ErrorAction SilentlyContinue | ForEach-Object {
try {
$vi = $_.VersionInfo
$nameBlob = @($vi.ProductName, $vi.FileDescription, $_.Name) -join ' '
if ($nameBlob -match '(Optimizely|Configured Commerce|Insite)') {
foreach ($cand in @($vi.ProductVersion, $vi.FileVersion)) {
if (-not [string]::IsNullOrWhiteSpace($cand)) {
$found.Add($cand)
}
}
}
} catch {}
}
}
# 2) Grep common config/text files for explicit version strings
Get-ChildItem -Path $Path -Recurse -Include web.config,appsettings*.json,*.config,*.txt -ErrorAction SilentlyContinue | ForEach-Object {
try {
$matches = Select-String -Path $_.FullName -Pattern '(?i)(version|configured\s*commerce|optimizely|insite)[^\r\n]{0,80}(\d+\.\d+\.\d+)' -AllMatches -ErrorAction SilentlyContinue
foreach ($m in $matches) {
foreach ($g in $m.Matches) {
if ($g.Groups.Count -ge 3) {
$found.Add($g.Groups[2].Value)
}
}
}
} catch {}
}
return $found
}
try {
if (-not (Test-Path $Root)) {
Write-Result 'UNKNOWN' "Path not found: $Root" 2
}
$candidates = Get-CandidateVersionStrings -Path $Root | Select-Object -Unique
if (-not $candidates -or $candidates.Count -eq 0) {
Write-Result 'UNKNOWN' 'No Optimizely Configured Commerce version evidence found in file metadata or config text.' 2
}
$normalized = @()
foreach ($c in $candidates) {
if ($null -ne (Normalize-VersionParts $c)) {
$normalized += $c
}
}
if (-not $normalized -or $normalized.Count -eq 0) {
Write-Result 'UNKNOWN' 'Version-like strings were found, but none were parseable as product versions.' 2
}
# Pick the highest parseable version we can find
$highest = $normalized[0]
foreach ($v in $normalized) {
$cmp = Compare-Version -A $v -B $highest
if ($cmp -eq 1) { $highest = $v }
}
$finalCmp = Compare-Version -A $highest -B $FixedVersion
if ($null -eq $finalCmp) {
Write-Result 'UNKNOWN' "Unable to compare discovered version '$highest' to fixed version '$FixedVersion'." 2
}
if ($finalCmp -ge 0) {
Write-Result 'PATCHED' "Discovered version '$highest' is at or above fixed version '$FixedVersion'." 0
} else {
Write-Result 'VULNERABLE' "Discovered version '$highest' is below fixed version '$FixedVersion'." 1
}
}
catch {
Write-Result 'UNKNOWN' ("Unhandled error: " + $_.Exception.Message) 3
}
If you remember one thing.
Sources
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.