What landed in CVE-land this week

This week's feed is unusually lopsided: one genuinely dangerous OS command injection in a widely-installed CMS module, one unauthenticated denial-of-service against an industrial sensor protocol, and a handful of withdrawn identifiers worth mentioning for what they teach about triage discipline. Here are the defensive takeaways and a short playbook for your on-call engineer.

The one you have to patch this weekend: CVE-2025-31692

CVE-2025-31692 is an OS command injection in Drupal's AI (Artificial Intelligence) contrib module, affecting all versions prior to 1.1.0. CVSS 7.5 understates the operational reality: Drupal AI sits in front of increasingly sensitive glue code — vector stores, embedding pipelines, third-party model providers holding API keys with real budget attached. A shell on the web tier costs you whatever settings.php and the environment expose to the LLM subsystem, which is often more than what the CMS itself holds.

The failure pattern is twenty years old: unsanitised input reaching a subprocess boundary. In modules that shell out to model runners, tokenisers, or on-disk conversion tools, the fix is the same:

// BAD — string concatenation into a shell context
$cmd = "python /opt/ai/run.py --prompt " . $userInput;
shell_exec($cmd);

// BETTER — arg vector, no shell interpolation
$proc = proc_open(
    ['python', '/opt/ai/run.py', '--prompt', $userInput],
    [0 => ['pipe','r'], 1 => ['pipe','w'], 2 => ['pipe','w']],
    $pipes
);

The advisory omits a proof-of-concept; we won't speculate on the exact injection sink. What matters is the detection surface. If you run Drupal AI, three items belong on the whiteboard by Monday:

  1. Inventory. drush pm:list --type=module --status=enabled | grep -i ai on every environment, including staging and the "temporary" review app that nobody has torn down since 2024.
  2. Upgrade path. Move to 1.1.0 or later. If your platform pins the module for compatibility reasons, put a WAF rule in front of the module's routes and treat it as incident-adjacent risk until the pin is resolved.
  3. Retro-hunt. Grep web-tier logs for POSTs to the module's endpoints with shell metacharacters (;, |, ` `, $(`, newline). If you ship Drupal logs to a SIEM, this search shape is a good starting point:
index=web sourcetype=drupal_access uri_path="*/ai/*"
| where match(uri_query, "[;|`]|\$\(|%0a|%7c")
| stats count by src_ip, uri_path, user_agent

Command injection in CMS contrib modules gets weaponised into opportunistic scanners within days. Don't wait for an Emerging Threats rule to confirm it.

The industrial-protocol one: CVE-2024-8751

CVE-2024-8751 (CVSS 7.5) is a Sopas ET interface flaw that lets an unauthenticated remote attacker rewrite a target device's IP address, producing a denial of service. Sopas ET is the configuration protocol used by a family of industrial sensors — LiDAR, safety scanners, code readers — commonly deployed on manufacturing floors and logistics lines.

Three points to internalize:

For shops that cannot patch immediately: put an ACL on the sensor's management port. Sopas ET typically runs on TCP/2111 and TCP/2112. An ACL constraining those ports to the engineering-workstation subnet takes fifteen minutes and stops the entire vulnerability class, not just this CVE.

# Example iptables rule for a Linux-based cell gateway
iptables -A FORWARD -p tcp -m multiport --dports 2111,2112 \
  -s 10.20.30.0/24 -d 10.20.40.0/24 -j ACCEPT
iptables -A FORWARD -p tcp -m multiport --dports 2111,2112 -j DROP

The withdrawn ones: CVE-2024-7033, -7034, -7038, -7039, -7040, -7959

Six CVE IDs in this week's feed were rejected or withdrawn by their assigning CNA. That is the program working, not a red flag. Rejections happen when an ID was reserved for a report that turned out to be a duplicate, a non-issue, out of scope for a CNA's products, or a misclassification.

For vulnerability-management pipelines, three rules:

  1. Ingest the REJECTED state as first-class data, not as a parse error. Your ticket queue should auto-close on rejection, not raise an alert.
  2. Do not delete the row. Rejected IDs still appear in older blog posts, scanner databases, and threat-intel reports. Keeping them queryable prevents a future analyst from re-triaging the same non-issue.
  3. **Track why a CVE was rejected when the CNA supplies a reason.** Duplicates in particular are worth linking to the surviving ID.

A weekend playbook

Thirty minutes before EOD Friday:

  1. Query your asset inventory for Drupal sites; flag any running the AI contrib module.
  2. Query your OT inventory for devices speaking Sopas ET; confirm each management port is ACL-constrained.
  3. Update your vuln-management pipeline's rejection handling so next week's withdrawals don't generate noise tickets.
  4. Add a detection rule for shell metacharacters against your CMS admin/API routes if you don't have one — it's cheap and catches more than this month's CVE.

None of this is glamorous. It is the difference between a Monday standup that opens with "we're patched" and one that opens with an incident bridge.

Verifiable security.