Like a booby-trapped Word doc, but only for the ~0.1% of developers who still edit Lisp in Emacs with auto-completion on
CVE-2024-53920 is a code-injection flaw in GNU Emacs's elisp-mode.el. When a user opens an untrusted .el (Emacs Lisp) file and either invokes elisp-completion-at-point or has Flymake/Flycheck auto-diagnosis enabled, Emacs performs unsafe macro expansion that can execute arbitrary system commands. The PoC is trivial — a single (rx (eval (call-process …))) form is enough to pop a shell. Affected versions span Emacs 26.1 through 29.4 and pre-release builds through 30.0.92. The fix shipped in Emacs 30.1 (released February 2025), which disables Flymake byte-compilation and completion-induced macro expansion for untrusted files.
The vendor CVSS of 7.8 HIGH is technically defensible on paper — AV:L/AC:L/PR:N/UI:R maps to 'user opens a file and something bad happens.' But in enterprise reality, this score dramatically overstates the risk. The affected population is vanishingly small: GNU Emacs holds roughly 0.06–0.1% IDE market share, and this bug only fires in Emacs Lisp editing mode specifically — not when editing Python, YAML, Terraform, or any other language. The attacker must socially engineer a developer into opening a .el file in Emacs with completion or Flymake active. There is no remote vector, no network exposure, no privilege escalation beyond the user's own session, and zero evidence of in-the-wild exploitation.
4 steps from start to impact.
Craft malicious Emacs Lisp file
.el file containing a macro form that triggers code execution during expansion — e.g., (rx (eval (call-process "cmd" ...))). No special tooling is required; the PoC is a single line of valid Elisp. The payload runs with the privileges of the Emacs process (i.e., the user).- Knowledge of Emacs Lisp macro expansion behavior
- Trivial to construct — no friction at this step
Deliver the file to the target
.el file onto the victim's filesystem. Delivery vectors include email attachment, a malicious Git repository, a pull request, or a shared network drive. The file must have a .el extension or be opened in emacs-lisp-mode to trigger the vulnerable code path.- Ability to send files to the target developer
- Target must be an Emacs user who works with
.elfiles
- Enterprise email gateways strip or quarantine unusual attachments
- Most developers do not routinely open
.elfiles from untrusted sources - Git-based delivery requires the victim to clone and open the specific file
Victim opens file in Emacs with active completion or Flymake
.el file in GNU Emacs. The vulnerability triggers only if elisp-completion-at-point is invoked (manually or via Company/Corfu auto-complete) OR if Flymake/Flycheck is enabled for Emacs Lisp buffers. Without either trigger, the file is inert. Many Emacs users have one or both enabled by default in their config for .el files.- Victim uses GNU Emacs 26.1–29.4
- Victim has Flymake, Flycheck, or auto-completion (Company/Corfu) active for elisp-mode
- Only Emacs Lisp developers typically have these features configured for
.elfiles - VS Code, JetBrains, Vim, and Neovim users (99%+ of developers) are unaffected
- Emacs users editing non-Lisp files are unaffected
call-process to /bin/sh)Arbitrary code execution as the user
- Steps 1–3 completed successfully
- No SYSTEM/root escalation — blast radius is one user session
- EDR behavioral detection should flag unexpected process trees from Emacs
emacs parentThe supporting signals.
| In-the-wild exploitation | None observed. Not listed in CISA KEV. No campaigns or threat actor usage reported as of September 2026. |
|---|---|
| Proof of concept | Public and trivial. Eshel Yaron published a full write-up and PoC on 2024-11-27. Single-line payload: (rx (eval (call-process ...))). |
| EPSS score | 0.00637 (~93rd percentile low). Exploitation probability effectively negligible. |
| KEV status | Not listed. No CISA KEV entry. |
| CVSS vector | CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H (7.8). Local vector with required user interaction. No network attack surface. |
| Affected versions | GNU Emacs 26.1 through 29.4 and pre-release 30.0.x through 30.0.92. |
| Fixed version | Emacs 30.1 (released 2025-02-23). Distro backports: Ubuntu USN-8011-1 (2026-02-04), Mageia MGASA-2024-0397. Red Hat tracking but no RHEL backport confirmed at time of writing. |
| Exposure data | Not applicable — Emacs is a local desktop application with no network listener. Shodan/Censys/GreyNoise have no relevant exposure data. Enlyft estimates ~84–1,228 companies use Emacs; IDE market share is ~0.06–0.1%. |
| Disclosure date | 2024-11-27 by Eshel Yaron. |
| Reporting researcher | Eshel Yaron — independent Emacs contributor and researcher. |
noisgate verdict.
The single most decisive factor is the vanishingly small exposed population: GNU Emacs holds ~0.1% IDE market share, and only the subset of users editing .el files with active completion or Flymake is vulnerable, reducing the reachable target set to a rounding error across a 10,000-host fleet. The local-only attack vector with mandatory social engineering further compresses real-world exploitability below the threshold for operational urgency.
Why this verdict
- Population filter: GNU Emacs has ~0.1% IDE market share. In a 10,000-host enterprise, the expected number of Emacs-for-Elisp-development workstations is in the single digits — possibly zero.
- Social engineering required: The attacker must deliver a
.elfile and convince the victim to open it in Emacs. This is a targeted spear-phishing prerequisite, not a spray-and-pray vector. - No network attack surface: AV:L means there is nothing to scan, nothing to exploit remotely, and no exposure to reduce. The entire chain is user-initiated.
- Role multiplier: Emacs is a developer workstation tool. It is not a domain controller, hypervisor, identity provider, CI/CD server, or any high-value-role component. Even if the chain succeeds, the blast radius is a single developer's user-space session — not fleet, domain, or supply-chain scale. No high-value-role floor applies.
- No exploitation evidence: Zero KEV listing, zero GreyNoise/campaign data, EPSS at 0.6% — the threat community has not operationalized this in 22 months since disclosure.
Why not higher?
Despite the trivial PoC, there is no remote attack vector, no privilege escalation beyond user context, and the affected population in any enterprise is negligibly small. The blast radius is strictly one workstation session. Upgrading to MEDIUM would require either evidence of active exploitation or a materially larger exposed population — neither exists.
Why not lower?
A public, trivial PoC does exist and the impact on a successfully targeted Emacs Lisp developer is full user-context code execution (C:H/I:H/A:H). Marking IGNORE would understate the risk for the rare enterprise that has a dedicated Emacs Lisp development team. LOW correctly signals 'patch when convenient, no urgency.'
What to do — in priority order.
- Disable Flymake and Flycheck for untrusted Elisp buffers — Add
(setq elisp-flymake-byte-compile nil)to site-wide Emacs config or setflymake-modeto nil inemacs-lisp-mode-hookfor files outside trusted directories. This eliminates the primary auto-trigger. No SLA — treat as backlog hygiene. - Set
enable-local-evalto nil — Prevents file-local variables from enabling Flymake or other unsafe evaluations. Add(setq enable-local-eval nil)to the sitedefault.el. Closes the secondary vector where a malicious file-local header re-enables Flymake. - Upgrade to Emacs 30.1+ — The definitive fix. Emacs 30.1 disables Flymake byte-compilation and completion-induced macro expansion for untrusted files. Roll out via package manager when convenient — no urgent SLA.
- Network segmentation / firewall rules — irrelevant; this is a local attack vector with no network component.
- WAF or IDS/IPS — the payload is a local file, not a network request. No signature will trigger.
- Application allowlisting for Emacs — blocking Emacs entirely would work but is disproportionate; the control should target the specific macro-expansion behavior, not the editor.
Crowdsourced verification payload.
Run on any Linux/macOS host where Emacs is installed. Execute as the regular user: bash check_cve_2024_53920.sh. No elevated privileges required.
#!/usr/bin/env bash
# CVE-2024-53920 checker — GNU Emacs elisp-mode unsafe macro expansion
# Run on target host. No root required.
if ! command -v emacs &>/dev/null; then
echo "UNKNOWN — Emacs is not installed on this host."
exit 2
fi
VERSION=$(emacs --version 2>/dev/null | head -1 | grep -oP '[0-9]+\.[0-9]+')
if [ -z "$VERSION" ]; then
echo "UNKNOWN — could not determine Emacs version."
exit 2
fi
MAJOR=$(echo "$VERSION" | cut -d. -f1)
MINOR=$(echo "$VERSION" | cut -d. -f2)
# Fixed in 30.1+
if [ "$MAJOR" -gt 30 ]; then
echo "PATCHED — Emacs $VERSION is >= 30.1."
exit 0
elif [ "$MAJOR" -eq 30 ] && [ "$MINOR" -ge 1 ]; then
echo "PATCHED — Emacs $VERSION is >= 30.1."
exit 0
else
echo "VULNERABLE — Emacs $VERSION is affected by CVE-2024-53920 (fixed in 30.1)."
exit 1
fiIf you remember one thing.
elisp-flymake-byte-compile nil) as a low-effort interim measure and queue the 30.1 upgrade into your next quarterly patch cycle. Do not burn emergency change-window budget on this.Sources
- Eshel Yaron — Emacs Arbitrary Code Execution write-up and PoC
- GitHub Advisory GHSA-8737-h7fg-9xgj
- GNU Emacs 30.1 release announcement (oss-security)
- Ubuntu CVE tracker — CVE-2024-53920
- Red Hat CVE entry — CVE-2024-53920
- SentinelOne Vulnerability Database — CVE-2024-53920
- 6sense — GNU Emacs market share data
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.