CVE-2025-54991: JupyterLab Desktop: DYLD injection inherits macOS TCC grants
MEDIUMJupyterLab Desktop for macOS, before 4.6.2-1, shipped with the allow-dyld-environment-variables entitlement, which lets an attacker with existing local code execution inject a dynamic library into the app and borrow the macOS privacy (TCC) permissions the user already granted it, such as access to Documents, Desktop and Downloads. It is not remotely exploitable and gives no initial access, so the CVSS 5.5 medium rating is fair. There is no KEV listing, no public exploit, no Nuclei template and no EPSS data, so active exploitation is unlikely today. The risk is mainly for data scientists' Macs that hold notebooks, datasets and credentials, where this lets malware reach protected folders without a new prompt. Upgrade to 4.6.2-1 or later and check which Mac endpoints still run older builds.
What is the risk?
Medium-to-low overall. CVSS 5.5 with a local attack vector, low privileges and no user interaction, and confidentiality impact only. Exploitation needs prior local code execution as the user and a TCC grant already given to JupyterLab Desktop. There is no known exploitation, no public PoC and no KEV listing, and the EPSS score is unavailable. Exposure is limited to macOS installs; Windows and Linux are not affected. The practical value to an attacker is as a post-compromise step that avoids a TCC prompt and the user noticing it.
How does the attack unfold?
What systems are affected?
| Package | Ecosystem | Vulnerable Range | Patched |
|---|---|---|---|
| Jupyter | pip | — | No patch |
Do you use Jupyter? You're affected.
How severe is it?
What is the attack surface?
What should I do?
1 step1) Upgrade JupyterLab Desktop to 4.6.2-1 or later on all macOS endpoints. 2) Inventory installed versions through MDM or endpoint management and remove older builds. 3) Check the app's TCC grants in System Settings > Privacy & Security and revoke any that are not needed. 4) Detect with EDR rules that flag DYLD_INSERT_LIBRARIES in the environment of JupyterLab Desktop processes, and unexpected dylib loads in the app. 5) Keep secrets out of Documents, Desktop and Downloads on data-science machines. 6) Apply standard hardening against local code execution, such as restricting unsigned binaries and using application allowlisting.
How is it classified?
Which compliance frameworks are affected?
This CVE is relevant to:
Frequently Asked Questions
What is CVE-2025-54991?
JupyterLab Desktop for macOS, before 4.6.2-1, shipped with the allow-dyld-environment-variables entitlement, which lets an attacker with existing local code execution inject a dynamic library into the app and borrow the macOS privacy (TCC) permissions the user already granted it, such as access to Documents, Desktop and Downloads. It is not remotely exploitable and gives no initial access, so the CVSS 5.5 medium rating is fair. There is no KEV listing, no public exploit, no Nuclei template and no EPSS data, so active exploitation is unlikely today. The risk is mainly for data scientists' Macs that hold notebooks, datasets and credentials, where this lets malware reach protected folders without a new prompt. Upgrade to 4.6.2-1 or later and check which Mac endpoints still run older builds.
Is CVE-2025-54991 actively exploited?
No confirmed active exploitation of CVE-2025-54991 has been reported, but organizations should still patch proactively.
How to fix CVE-2025-54991?
1) Upgrade JupyterLab Desktop to 4.6.2-1 or later on all macOS endpoints. 2) Inventory installed versions through MDM or endpoint management and remove older builds. 3) Check the app's TCC grants in System Settings > Privacy & Security and revoke any that are not needed. 4) Detect with EDR rules that flag DYLD_INSERT_LIBRARIES in the environment of JupyterLab Desktop processes, and unexpected dylib loads in the app. 5) Keep secrets out of Documents, Desktop and Downloads on data-science machines. 6) Apply standard hardening against local code execution, such as restricting unsigned binaries and using application allowlisting.
What systems are affected by CVE-2025-54991?
This vulnerability affects the following AI/ML architecture patterns: Developer workstations, Notebook environments, Data science desktops.
What is the CVSS score for CVE-2025-54991?
CVE-2025-54991 has a CVSS v3.1 base score of 5.5 (MEDIUM).
What is the AI security impact?
Affected AI Architectures
MITRE ATLAS Techniques
AML.T0037Data from Local SystemAML.T0107Exploitation for Defense EvasionCompliance Controls Affected
What are the technical details?
Original Advisory
JupyterLab Desktop is the cross-platform desktop application for JupyterLab. Prior to 4.6.2-1, JupyterLab Desktop for macOS declared the com.apple.security.cs.allow-dyld-environment-variables entitlement, allowing the dynamic linker to honor DYLD_INSERT_LIBRARIES despite the hardened runtime. An attacker who can already execute code as the current user can load an arbitrary dynamic library into the JupyterLab Desktop process and inherit TCC permissions previously granted to the application, including access to protected Documents, Desktop, or Downloads folders without another macOS prompt. Exploitation requires existing local code execution and prior TCC grants; it does not provide initial or remote code execution. Windows and Linux are not affected. This vulnerability is fixed in 4.6.2-1.
Exploitation Scenario
Malware or a malicious package, for example a trojanized Python dependency installed in a notebook workflow, runs as the user on a Mac. The user has previously allowed JupyterLab Desktop to access Documents and Downloads. The attacker launches JupyterLab Desktop with DYLD_INSERT_LIBRARIES pointing to a malicious dylib. The library loads into the app, which inherits its TCC permissions, and silently reads datasets, notebooks and credential files from protected folders. The attacker then sends them out through normal network channels.
Weaknesses (CWE)
CWE-250Execution with Unnecessary PrivilegesPrimaryCWE-693Protection Mechanism FailurePrimaryCWE-250Execution with Unnecessary PrivilegesCWE-693Protection Mechanism FailureCWE-250 — Execution with Unnecessary Privileges: The product performs an operation at a privilege level that is higher than the minimum level required, which creates new weaknesses or amplifies the consequences of other weaknesses.
- [Architecture and Design, Operation] Run your code using the lowest privileges that are required to accomplish the necessary tasks [REF-76]. If possible, create isolated accounts with limited privileges that are only used for a single task. That way, a successful attack will not immediately give the attacker access to the rest of the software or its environment. For example, database applications rarely need to run as the database administrator, especially in day-to-day operations.
- [Architecture and Design] Identify the functionality that requires additional privileges, such as access to privileged operating system resources. Wrap and centralize this functionality if possible, and isolate the privileged code as much as possible from other code [REF-76]. Raise privileges as late as possible, and drop them as soon as possible to avoid CWE-271. Avoid weaknesses such as CWE-288 and CWE-420 by protecting all possible communication channels that could interact with the privileged code, such as a secondary socket that is only intended to be accessed by administrators.
Source: MITRE CWE corpus.
CVSS Vector
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:NReferences
Timeline
Related Vulnerabilities
CVE-2023-2557410.0JupyterHub LTI13: JWT forgery enables full auth bypass
Same package: jupyterCVE-2024-3970010.0JupyterLab extension-template: CI workflow RCE
Same package: jupyterCVE-2026-441809.8Jupyter Enterprise Gateway: root privilege bypass in Kubernetes
Same package: jupyterCVE-2026-235379.1Feast: unauth file write to RCE via /save-document
Same package: jupyterCVE-2026-545279.0jupyterlab-git: stored XSS escalates to full RCE
Same package: jupyter