DEV Community

Cover image for KEV: V8 CVE-2025-10585 Hits Electron Apps
Pentest Testing Corp
Pentest Testing Corp

Posted on

KEV: V8 CVE-2025-10585 Hits Electron Apps

TL;DR (for devs)

  • CVE-2025-10585 is a V8 type-confusion bug added to CISA’s KEV on Sept 23, 2025. Treat it as urgent.
  • Patched Chromium line: ≥ 140.0.7339.185 (and later dot-releases).
  • Electron impact: many desktop apps bundle Chromium, so browser patching alone isn’t enough—you must upgrade Electron to a build that embeds a fixed Chromium (or hot-patch/rebuild).
  • Ship a rollout plan: force auto-updates, invalidate old installers, block outdated runtimes at startup, and prove the fix in CI via SCA/KEV checks.

KEV: V8 CVE-2025-10585 Hits Electron Apps


What KEV means & why CVE-2025-10585 matters

CISA’s Known Exploited Vulnerabilities (KEV) catalog flags vulnerabilities with evidence of in-the-wild exploitation. When a V8 bug like CVE-2025-10585 lands in KEV, it’s not theoretical—real attackers are using it. For commercial apps and enterprise deployments, KEV is essentially a must-fix list.

Patch trains (Chrome/Chromium): The vendor-fixed boundary for this bug is Chromium/Chrome 140.0.7339.185 and above. Anything below that needs mitigation or upgrade.

Practical implication: if your app bundles an older Chromium through Electron, users remain vulnerable even if their system browser is up-to-date.


Why Electron teams must act now

Electron apps embed a specific Chromium and V8 snapshot. That’s your browser engine, JS runtime, and attack surface—all inside your installer. Updating only the OS browser doesn’t touch that embedded runtime.

Action items:

  1. Identify the Chromium version in your shipped Electron build(s).
  2. Upgrade to an Electron release that embeds Chromium ≥ 140.0.7339.185.
  3. Enforce auto-updates and block outdated runtimes at app startup.
  4. Prove the fix in CI with SCA/KEV gates.

Free Website Vulnerability Scanner — Landing Page

Screenshot of the free tools webpage where you can access security assessment tools.Screenshot of the free tools webpage where you can access security assessment tools.


Dev cookbook: verify, upgrade, block, and prove

1) Detect your embedded Chromium at runtime

// main.ts
import { app, dialog } from 'electron';

const REQUIRED_CHROMIUM = '140.0.7339.185';

function cmpVersion(a: string, b: string): number {
  // Compares dotted versions like 140.0.7339.185
  const ap = a.split('.').map(Number);
  const bp = b.split('.').map(Number);
  const len = Math.max(ap.length, bp.length);
  for (let i = 0; i < len; i++) {
    const ai = ap[i] ?? 0, bi = bp[i] ?? 0;
    if (ai > bi) return 1;
    if (ai < bi) return -1;
  }
  return 0;
}

app.on('ready', () => {
  const current = process.versions.chrome; // e.g., "140.0.7339.133"
  if (cmpVersion(current, REQUIRED_CHROMIUM) < 0) {
    dialog.showErrorBox(
      'Security Update Required',
      `Your app runtime (${current}) is below the patched Chromium ` +
      `(${REQUIRED_CHROMIUM}). The app will exit until updated.`
    );
    app.quit();
    return;
  }
  // ...continue launching BrowserWindow, etc.
});
Enter fullscreen mode Exit fullscreen mode

Tip: Also log process.versions.v8 for audit evidence.


2) Map Electron → Chromium to pick a safe Electron target

# Install helper mapping
npm i -D electron-to-chromium
Enter fullscreen mode Exit fullscreen mode
// tools/electron-chromium-check.mjs
import { versions } from 'electron-to-chromium';

// Find Electron versions that meet a minimum Chromium
const REQUIRED = '140.0.7339.185';

function cmp(a, b) { // same comparator as above
  const ap = a.split('.').map(Number), bp = b.split('.').map(Number);
  const len = Math.max(ap.length, bp.length);
  for (let i = 0; i < len; i++) {
    const ai = ap[i] ?? 0, bi = bp[i] ?? 0;
    if (ai !== bi) return ai - bi;
  }
  return 0;
}

const candidates = [];
for (const [electron, chromium] of Object.entries(versions)) {
  if (cmp(chromium, REQUIRED) >= 0) candidates.push({ electron, chromium });
}

candidates
  .sort((a, b) => cmp(a.chromium, b.chromium))
  .slice(0, 10)
  .forEach(c => console.log(`Electron ${c.electron} → Chromium ${c.chromium}`));
Enter fullscreen mode Exit fullscreen mode

Run it in CI to suggest the minimum Electron you should upgrade to.


3) CI gate: fail builds if your bundle is below the fixed Chromium

# .github/workflows/security-gates.yml
name: security-gates
on: [push, pull_request]
jobs:
  chromium-floor:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: { node-version: '22' }
      - run: npm ci
      - run: node tools/electron-chromium-check.mjs > chromium_candidates.txt
      - name: Check runtime floor
        run: |
          REQUIRED="140.0.7339.185"
          CURRENT=$(node -e "console.log(require('electron-to-chromium/versions').versions[process.env.ELECTRON_TAG||'latest'])" || echo "0.0.0.0")
          echo "Electron→Chromium: $CURRENT (required >= $REQUIRED)"
          node -e "
            const r='$REQUIRED', c='$CURRENT';
            const p=x=>x.split('.').map(Number); const A=p(c), B=p(r);
            let ok=true; for(let i=0;i<4;i++){const d=(A[i]||0)-(B[i]||0); if(d<0){ok=false;break;} if(d>0){break;}}
            if(!ok){console.error('FAIL: Chromium below KEV floor'); process.exit(1);} else {console.log('OK');}
          "
Enter fullscreen mode Exit fullscreen mode

4) CI gate: alert if KEV lists your dependencies (no external links in content)

Fetch KEV JSON via a secure pipeline variable (e.g., KEV_FEED) and check for CVE-2025-10585 (or any other CVEs you track):

# tools/kev-check.sh
set -euo pipefail
: "${KEV_FEED:?Set KEV_FEED to a JSON feed path}"
: "${CVE_LIST:=CVE-2025-10585}"
if jq -e --arg cves "$CVE_LIST" '
  .vulnerabilities as $v
  | ($cves | split(",") | map(.)) as $search
  | [ .[] , $v[] ]  # allow either top-level or nested arrays
  | any($search[]; .cveID == .)
' "$KEV_FEED" > /dev/null; then
  echo "KEV match found; enforce Chromium floor and force update."
  exit 1
else
  echo "No KEV match."
fi
Enter fullscreen mode Exit fullscreen mode

Wire into your workflow:

- name: KEV gate
  run: bash tools/kev-check.sh
  env:
    KEV_FEED: ./security/known_exploited_vulnerabilities.json  # stored artifact
    CVE_LIST: CVE-2025-10585
Enter fullscreen mode Exit fullscreen mode

5) Enforce auto-updates for Electron (example: electron-updater)

npm i electron-updater
Enter fullscreen mode Exit fullscreen mode
// updater.ts
import { autoUpdater } from 'electron-updater';
import { app } from 'electron';

export function initAutoUpdate() {
  autoUpdater.autoDownload = true;
  autoUpdater.autoInstallOnAppQuit = true; // install silently on restart
  autoUpdater.on('update-available', () => console.log('Update available…'));
  autoUpdater.on('update-downloaded', () => console.log('Update downloaded; will install on quit.'));
  autoUpdater.checkForUpdatesAndNotify({
    title: 'Security Update',
    body: 'A critical security update is ready. Restart to finish installing.'
  });
}

app.on('ready', initAutoUpdate);
Enter fullscreen mode Exit fullscreen mode

Tip: Publish via GitHub Releases, S3, or self-hosted—just ensure TLS, signed artifacts, and digest pinning in your pipeline.


6) Invalidate old installers (stop the bleeding)

  • S3/CloudFront example:
  # Remove legacy installers
  aws s3 rm s3://my-app-downloads/releases/ --recursive --exclude "*" \
    --include "MyApp-Setup-*-Windows.exe" --include "MyApp-*-mac.zip"

  # Invalidate CDN cache
  aws cloudfront create-invalidation --distribution-id E123ABC \
    --paths "/releases/*"
Enter fullscreen mode Exit fullscreen mode
  • Vendor portal/self-hosted: rotate download links, detach legacy tags, and rebuild release notes to steer users to the fixed build only.

7) Block outdated engines at startup (defense in depth)

Add a kill-switch that remote-configures the minimum required Chromium:

// config/minimums.json (served by your API or bundled)
{ "chromiumMin": "140.0.7339.185" }
Enter fullscreen mode Exit fullscreen mode
// main.ts (excerpt)
import fetch from 'node-fetch';
async function fetchMin() {
  try {
    const res = await fetch('https://update.myapp.com/minimums.json', { timeout: 3000 });
    const { chromiumMin } = await res.json();
    return chromiumMin || '140.0.7339.185';
  } catch {
    return '140.0.7339.185'; // fail-safe floor
  }
}
Enter fullscreen mode Exit fullscreen mode

Sample Report to check Website Vulnerability— (exported from the tool)

Sample vulnerability assessment report generated with our free tool, providing insights into possible vulnerabilities.Sample vulnerability assessment report generated with our free tool, providing insights into possible vulnerabilities.


Rollout checklist (copy/paste)

  1. Cut a new Electron build that embeds Chromium ≥ 140.0.7339.185.
  2. Turn on forced auto-updates (electron-updater) + restart prompts.
  3. Invalidate old installers and remove legacy release assets.
  4. Startup block for runtimes below 140.0.7339.185.
  5. CI gates: (a) Electron→Chromium mapping floor, (b) KEV feed check.
  6. Audit evidence: archive process.versions output, build logs, and SBOM diffs.
  7. External risk scan while you roll: run a quick surface check with our free tool.

Quick verification: SCA diff that your build is fixed

Generate an SBOM and compare across builds:

# Before & after SBOM
npx @cyclonedx/cyclonedx-npm --output-file sbom-before.json
# …upgrade Electron & rebuild…
npx @cyclonedx/cyclonedx-npm --output-file sbom-after.json

# Diff for audit
jq -S . sbom-before.json > a.json && jq -S . sbom-after.json > b.json && diff -u a.json b.json | tee sbom.diff
Enter fullscreen mode Exit fullscreen mode

Store the diff and a versions.json like:

{
  "electron": "38.?.?",
  "chromium": "140.0.7339.2xx",
  "v8": "14.0.x",
  "fixedFor": ["CVE-2025-10585"]
}
Enter fullscreen mode Exit fullscreen mode

Add runtime telemetry (optional but useful)

Report aggregated counts of blocked outdated runs (no PII):

import os from 'os';
function reportBlock(current: string, required: string) {
  fetch('https://telemetry.myapp.com/chromium-floor', {
    method: 'POST',
    headers: {'content-type':'application/json'},
    body: JSON.stringify({
      current, required, os: os.platform(), arch: os.arch(), appVersion: app.getVersion()
    })
  }).catch(()=>{});
}
Enter fullscreen mode Exit fullscreen mode

Try this while you roll out patches

While your desktop users update, run an external surface check to catch obvious exposures:

👉 Free Website Vulnerability Scanner: https://free.pentesttesting.com/


Related services (engage our team)

Prefer a consultation? Email query@pentesttesting.com.


Further reading from our blog


Final call to action

If your Electron runtime isn’t Chromium ≥ 140.0.7339.185, don’t ship.
Patch, prove it in CI, and block outdated engines at startup. If you need help planning or executing the rollout, our Risk Assessment and Remediation teams can jump in today.


(Optional) Developer appendix: one-liner checks

Print embedded versions at runtime:

console.log(process.versions); // { node, chrome, v8, electron, ... }
Enter fullscreen mode Exit fullscreen mode

Gate your release in package.json scripts:

{
  "scripts": {
    "prepack": "node tools/electron-chromium-check.mjs || (echo 'Chromium below KEV floor' && exit 1)"
  }
}
Enter fullscreen mode Exit fullscreen mode

Top comments (0)