← Back to Feed CACHED · 2026-05-17 09:42:19 · cache_key CVE-2025-29912
CVE-2025-0214 · CWE-74 · Disclosed 2025-01-04

A vulnerability was found in TMD Custom Header Menu 4

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

This is a bad lock on a room that the attacker usually has to be invited into first

CVE-2025-0214 is a SQL injection in the third-party TMD Custom Header Menu extension for OpenCart. The public advisory says the vulnerable OpenCart 4 release is 4.0.0.1, with an older OpenCart 3 branch also affected, and the bug sits in admin-side handling of the headermenu_id parameter on routes reached through /admin/index.php; the parameter is fed into a database query without proper neutralization.

The vendor's MEDIUM 4.1 is still too generous for patch triage at enterprise scale. The decisive friction is that exploitation needs authenticated access to the OpenCart admin UI or a stolen valid admin session plus user_token, which makes this a *post-initial-access* bug in a relatively niche extension, not an internet-sweepable foothold; the public PoC and real data-exposure potential keep it above IGNORE, but not by much.

"This is a niche, post-auth admin-panel SQLi with real impact but lousy attacker economics."
02 · The Attack Path

3 steps from start to impact.

STEP 01

Reach an OpenCart admin session

The attacker first needs a legitimate path into the OpenCart backend: valid admin credentials, a hijacked admin cookie, or a way to run script in an admin browser context. The public write-up explicitly notes that a valid session cookie and user_token are required for exploitation, and even demonstrates a browser-console PoC that assumes an already logged-in admin.
Conditions required:
  • OpenCart store has the TMD Custom Header Menu extension installed
  • Attacker has authenticated admin access, a stolen session, or equivalent admin-browser code execution
  • Admin route is reachable
Where this breaks in practice:
  • This is not unauthenticated remote exploitation
  • Many enterprises do not expose admin paths broadly to the internet
  • Credential theft, session theft, or prior XSS/phishing is a separate compromise stage
Detection/coverage: External vuln scanners will usually miss this unless provided authenticated admin coverage. Web logs that record admin requests with anomalous headermenu_id payloads can catch it; otherwise detection is weak until after session compromise.
STEP 02

Trigger the vulnerable admin route with public PoC

Using the advisory's JavaScript PoC or a tool like sqlmap, the attacker sends crafted requests to the extension's admin form route and injects SQL through headermenu_id. The gist shows boolean-based, error-based, time-based, and UNION-based techniques against the parameter once a valid user_token is present.
Conditions required:
  • Valid admin user_token in request
  • Extension route permissions available to the compromised account
  • Database-backed vulnerable code path still present
Where this breaks in practice:
  • Attack complexity is higher than commodity one-shot exploits
  • OpenCart user-group permissions can block extension-specific access for some admin roles
  • Some patched or manually modified installs may already cast/escape the parameter
Detection/coverage: WAF coverage is inconsistent because this is an authenticated admin endpoint and the parameter name is niche. Application logs and reverse-proxy logs are the best bet if they retain query strings for /admin/index.php.
STEP 03

Exfiltrate or tamper with store data

Successful injection exposes the store database to extraction or manipulation. The advisory specifically calls out admin-user data exfiltration and notes that a full database dump is feasible with sqlmap, which can include customer PII, order data, and any sensitive records stored in MySQL.
Conditions required:
  • Vulnerable query executes with sufficient DB read/write capability
  • Database contains sensitive customer or admin records
Where this breaks in practice:
  • Blast radius is generally limited to the affected store/app database
  • An attacker already holding admin access often has other easier abuse paths inside OpenCart
  • Operational noise from full dumping may be noticeable in DB or web logs
Detection/coverage: DB monitoring may catch long-running, repetitive, or sleep-based queries. In many SMB ecommerce deployments, though, there is little to no database telemetry, so post-event visibility is often poor.
03 · Intelligence Metadata

The supporting signals.

In-the-wild statusNo authoritative evidence of active exploitation found in public sources reviewed. Not listed in CISA KEV.
Proof-of-concept availabilityYes. Researcher mcdruid published a public advisory and PoC, including browser-console exploitation and sqlmap output: GitHub Gist.
EPSSUser-supplied EPSS is 0.00112, which is extremely low in absolute terms. Percentile was not confirmed from an authoritative EPSS score page during review.
KEV statusNo. CISA's Known Exploited Vulnerabilities Catalog does not contain CVE-2025-0214.
CVSS vector reality checkCVSS:3.1/AV:N/AC:H/PR:H/UI:N/S:U/C:L/I:L/A:L correctly captures the biggest suppressor: high privileges required. In practice that means *post-auth admin abuse*, not fresh external compromise.
Affected versionsPublic advisory names TMD Custom Header Menu 4.0.0.1 on OpenCart as vulnerable and says an OpenCart 3 release from 2017 is also affected. Testing in the advisory was done against OpenCart 4.0.2.3 and 3.0.4.0 with the extension installed.
Fixed versionThe researcher timeline says TMD released a fix on 2024-12-30, but a public version number was not verified from accessible vendor pages. Treat version validation as manual until you confirm the installed package contents.
Exposure / scanabilityThis is not broadly internet-sweepable the way pre-auth web bugs are, because the vulnerable path sits behind /admin and needs a valid session plus token. Public internet-scale exposure telemetry specific to this extension was not located; the extension page shows substantial marketplace visibility/download interest, but that is not exposure proof.
Disclosure timelineResearcher timeline: reported 2024-12-27, vendor acknowledged 2024-12-28, fix released 2024-12-30, CVE requested 2025-01-03; NVD publication date 2025-01-04.
Reporter / sourceReported by mcdruid, with the CNA/source shown as VulDB in the NVD record.
04 · The Call

noisgate verdict.

Final Verdict
DOWNGRADED to LOW (2.8/10)

The single most important factor is the attacker position requirement: this bug needs authenticated OpenCart admin access or a stolen admin session plus user_token. That turns a technically real SQLi into a *post-compromise privilege-abuse issue* in a niche extension, which sharply limits reachable population and attacker ROI.

HIGH Exploit precondition requires authenticated admin context or equivalent session theft
MEDIUM Patch/version identification beyond vulnerable 4.0.0.1
HIGH No current evidence of KEV listing or public in-the-wild exploitation

Why this verdict

  • Major downgrade for attacker position: exploitation needs admin-panel access, a stolen admin cookie, or admin-browser script execution. That is already a serious prior compromise stage.
  • Population is narrow: this is a third-party OpenCart extension, not OpenCart core, so the exposed estate is a small subset of ecommerce installs rather than a broad enterprise platform surface.
  • Threat pressure is weak: no KEV entry, no confirmed active exploitation, and the supplied EPSS is extremely low despite public PoC availability.

Why not higher?

If this were unauthenticated or even low-privilege authenticated, it would climb fast because SQLi against a live store database is nasty. But requiring high privileges plus a valid session token means most attackers who can use this have already crossed the hard boundary.

Why not lower?

This is still genuine SQL injection with a public PoC, not a theoretical bug. On a live store, successful abuse can expose customer data, admin credentials, and order records, so defenders should not dismiss it outright if the extension is present.

05 · Compensating Control

What to do — in priority order.

  1. Restrict admin reachability — Put /admin behind IP allowlists, VPN, or an identity-aware proxy so fewer attackers can ever satisfy the precondition. For a LOW verdict there is no SLA; treat as backlog hygiene, but this is the best risk-reduction move if you cannot patch immediately.
  2. Audit admin roles — Review OpenCart user groups and remove extension access from anyone who does not need it; the exploit path dies if the compromised user cannot reach the module route. For a LOW verdict there is no SLA; treat as backlog hygiene, but make it part of the next permissions review.
  3. Hunt for session misuse — Search reverse-proxy and application logs for suspicious /admin/index.php requests containing headermenu_id= with SQL metacharacters, especially from unusual IPs or admin accounts. For a LOW verdict there is no SLA; treat as backlog hygiene, but do it promptly if the store handles regulated customer data.
  4. Disable or remove the extension if unused — If the business does not actively use TMD Custom Header Menu, removing the plugin is cleaner than carrying a low-value third-party risk surface. For a LOW verdict there is no SLA; treat as backlog hygiene, and this should be part of normal extension rationalization.
What doesn't work
  • A generic perimeter WAF is not enough, because the vulnerable route is typically behind authenticated admin access and the exploit can ride a valid session.
  • Password rotation alone does not solve stolen-session scenarios; the advisory explicitly discusses valid session cookies and user_token use.
  • Relying on unauthenticated external scanning will miss most of the real exposure because the vulnerable code path is in the admin plane.
06 · Verification

Crowdsourced verification payload.

Run this on the target OpenCart host against the web root, for example: sudo bash verify-cve-2025-0214.sh /var/www/html. Read access to the OpenCart files is required; root is helpful but not mandatory if the web tree is readable.

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash
# verify-cve-2025-0214.sh
# Check OpenCart filesystem for the TMD Custom Header Menu extension and look for
# unsanitized use of the headermenu_id parameter in admin-side PHP code.
#
# Exit codes:
#   0 = PATCHED
#   1 = VULNERABLE
#   2 = UNKNOWN

set -u

WEBROOT="${1:-}"
if [[ -z "$WEBROOT" || ! -d "$WEBROOT" ]]; then
  echo "UNKNOWN: usage: $0 /path/to/opencart/webroot"
  exit 2
fi

# Candidate files/dirs commonly seen for this extension across OC3/OC4 layouts
mapfile -t CANDIDATES < <(find "$WEBROOT" \
  \( -iname '*tmdcustomheader*' -o -iname '*headermenu*' \) \
  2>/dev/null)

if [[ ${#CANDIDATES[@]} -eq 0 ]]; then
  echo "UNKNOWN: no TMD Custom Header Menu extension artifacts found under $WEBROOT"
  exit 2
fi

VULN_FOUND=0
PATCHED_FOUND=0
VERSION_HIT=0

for f in "${CANDIDATES[@]}"; do
  if [[ -f "$f" ]]; then
    # Version hint
    if grep -Eq '4\.0\.0\.1' "$f" 2>/dev/null; then
      VERSION_HIT=1
    fi

    # Look for direct request usage around headermenu_id
    if grep -Eq "headermenu_id" "$f" 2>/dev/null; then
      # Patched indicators: explicit cast or escaping applied to headermenu_id
      if grep -Eq "\(int\)[^\n]*headermenu_id|intval\([^\n]*headermenu_id|escape\([^\n]*headermenu_id" "$f" 2>/dev/null; then
        PATCHED_FOUND=1
      fi

      # Vulnerable indicators: raw request parameter pulled and later used in query-building code
      if grep -Eq "request->get\['headermenu_id'\]|\$_GET\['headermenu_id'\]" "$f" 2>/dev/null; then
        if grep -Eq "db->query\(|SELECT |UPDATE |DELETE |INSERT " "$f" 2>/dev/null; then
          if ! grep -Eq "\(int\)[^\n]*headermenu_id|intval\([^\n]*headermenu_id|escape\([^\n]*headermenu_id" "$f" 2>/dev/null; then
            VULN_FOUND=1
          fi
        fi
      fi
    fi
  fi
done

if [[ $VULN_FOUND -eq 1 ]]; then
  if [[ $VERSION_HIT -eq 1 ]]; then
    echo "VULNERABLE: extension artifacts include version 4.0.0.1 and unsanitized headermenu_id handling"
  else
    echo "VULNERABLE: unsanitized headermenu_id handling found in TMD Custom Header Menu code"
  fi
  exit 1
fi

if [[ $PATCHED_FOUND -eq 1 ]]; then
  echo "PATCHED: extension present and headermenu_id appears to be cast/escaped before query use"
  exit 0
fi

echo "UNKNOWN: extension artifacts found, but vulnerable/patched state could not be determined conclusively"
exit 2
07 · Bottom Line

If you remember one thing.

TL;DR
Monday morning: first confirm whether you actually run TMD Custom Header Menu anywhere; if not, close the ticket with documented non-applicability. If you do run it, this is LOW by reassessed risk, so there is no noisgate mitigation SLA — treat as backlog hygiene, and there is likewise no noisgate remediation SLA beyond normal backlog handling for LOW; update/remove the extension in the next routine change window, and in the meantime tighten /admin exposure and admin-role permissions as cheap guardrails.

Sources

  1. NVD record for CVE-2025-0214
  2. Public advisory and PoC by mcdruid
  3. VulDB entry VDB-290159
  4. OpenCart user groups and admin permissions
  5. OpenCart extension developer guide
  6. TMD Custom Header Menu product page
  7. CISA Known Exploited Vulnerabilities Catalog
  8. FIRST EPSS model overview
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.