CVE-2025-30370
jupyterlab-git has a command injection vulnerability in "Open Git Repository in Terminal"
jupyterlab-git is a JupyterLab extension for version control using Git. On many platforms, a third party can create a Git repository under a name that includes a shell command substitution string in the syntax $(<command>). These directory names are allowed in macOS and a majority of Linux distributions. If a user starts jupyter-lab in a parent directory of this inappropriately-named Git repository, opens it, and clicks "Git > Open Git Repository in Terminal" from the menu bar, then the injected command <command> is run in the user's shell without the user's permission. This issue is occurring because when that menu entry is clicked, jupyterlab-git opens the terminal and runs cd <git-repo-path> through the shell to set the current directory. Doing so runs any command substitution strings present in the directory name, which leads to the command injection issue described here. A previous patch provided an incomplete fix. This vulnerability is fixed in 0.51.1.
Attack profile
How easy it is to exploit
- Attack vector
- Local
- Complexity
- High
- Privileges needed
- Low
- User interaction
- Required
What an attacker can affect
- Confidentiality
- Low
- Integrity
- High
- Availability
- High
Exploit likelihood
What each source reports
CVE List Score used
7.4
jupyterlab-git has a command injection vulnerability in "Open Git Repository in Terminal"
jupyterlab-git is a JupyterLab extension for version control using Git. On many platforms, a third party can create a Git repository under a name that includes a shell command substitution string in the syntax $(<command>). These directory names are allowed in macOS and a majority of Linux distributions. If a user starts jupyter-lab in a parent directory of this inappropriately-named Git repository, opens it, and clicks "Git > Open Git Repository in Terminal" from the menu bar, then the injected command <command> is run in the user's shell without the user's permission. This issue is occurring because when that menu entry is clicked, jupyterlab-git opens the terminal and runs cd <git-repo-path> through the shell to set the current directory. Doing so runs any command substitution strings present in the directory name, which leads to the command injection issue described here. A previous patch provided an incomplete fix. This vulnerability is fixed in 0.51.1.
- Record
CVE-2025-30370- CVSS 3.1
- 7.4 High
CVSS:3.1/AV:L/AC:H/PR:L/UI:R/S:C/C:L/I:H/A:H - Weakness
- CWE-78
- Updated
- 2026-11-02
EUVDEUVD-2025-9739
7.4
jupyterlab-git is a JupyterLab extension for version control using Git. On many platforms, a third party can create a Git repository under a name that includes a shell command substitution string in the syntax $(<command>). These directory names are allowed in macOS and a majority of Linux distributions. If a user starts jupyter-lab in a parent directory of this inappropriately-named Git repository, opens it, and clicks "Git > Open Git Repository in Terminal" from the menu bar, then the injected command <command> is run in the user's shell without the user's permission. This issue is occurring because when that menu entry is clicked, jupyterlab-git opens the terminal and runs cd <git-repo-path> through the shell to set the current directory. Doing so runs any command substitution strings present in the directory name, which leads to the command injection issue described here. A previous patch provided an incomplete fix. This vulnerability is fixed in 0.51.1.
- Record
EUVD-2025-9739- CVSS 3.1
- 7.4 High
CVSS:3.1/AV:L/AC:H/PR:L/UI:R/S:C/C:L/I:H/A:H - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-cj5w-8mjf-r5f8
7.4
jupyterlab-git has a command injection vulnerability in "Open Git Repository in Terminal"
Overview
On many platforms, a third party can create a Git repository under a name that includes a shell command substitution ^1 string in the syntax $(<command>). These directory names are allowed in macOS and a majority of Linux distributions ^2. If a user starts jupyter-lab in a parent directory of this inappropriately-named Git repository, opens it, and clicks "Git > Open Git Repository in Terminal" from the menu bar, then the injected command <command> is run in the user's shell without the user's permission.
This issue is occurring because when that menu entry is clicked, jupyterlab-git opens the terminal and runs cd <git-repo-path> through the shell to set the current directory ^3. Doing so runs any command substitution strings present in the directory name, which leads to the command injection issue described here. A previous patch provided an incomplete fix ^4.
Scope of Impact
This issue allows for arbitrary code execution via command injection. A wide range of actions are permitted by this issue, including but not limited to: modifying files, exfiltrating data, halting services, or compromising the server's security rules.
We have scanned the source code of jupyterlab-git for other command injection risks, and have not found any at the time of writing.
This issue was reproduced on the latest release of jupyterlab-git, v0.51.0. The steps taken to reproduce this issue are described in the "Proof-of-concept" section below.
Proof-of-concept
-
Create a new directory via
mkdir test/ && cd test/. -
Create a new Git repository under
test/with a command substitution string in the directory name by running these commands:
mkdir '$(touch pwned.txt)'
cd '$(touch pwned.txt)/'
git init
cd ..
- Start JupyterLab from
test/by running jupyter lab. - With JupyterLab open in the browser, double click on
$(touch pwned.txt)in the file browser. - From the top menu bar, click "Git > Open Git Repository in Terminal".
- Verify that
pwned.txtis created undertest/. This demonstrates the command injection issue described here.
Proof-of-concept mitigation
The issue can be mitigated by the patch shown below.
<details><summary>Patch (click to expand)</summary>
diff --git a/src/commandsAndMenu.tsx b/src/commandsAndMenu.tsx
index 3779a6c..71ddcea 100644
--- a/src/commandsAndMenu.tsx
+++ b/src/commandsAndMenu.tsx
@@ -164,31 +164,13 @@ export function addCommands(
label: trans.__('Open Git Repository in Terminal'),
caption: trans.__('Open a New Terminal to the Git Repository'),
execute: async args => {
- const main = (await commands.execute(
- 'terminal:create-new',
- args
- )) as MainAreaWidget<ITerminal.ITerminal>;
+ const cwd = gitModel.pathRepository;
+ const main = (await commands.execute('terminal:create-new', {
+ ...args,
+ cwd
+ })) as MainAreaWidget<ITerminal.ITerminal>;
- try {
- if (gitModel.pathRepository !== null) {
- const terminal = main.content;
- terminal.session.send({
- type: 'stdin',
- content: [
- `cd "${gitModel.pathRepository
- .split('"')
- .join('\\"')
- .split('`')
- .join('\\`')}"\n`
- ]
- });
- }
-
- return main;
- } catch (e) {
- console.error(e);
- main.dispose();
- }
+ return main;
</details>
This patch removes the cd <git-repo-path> shell command that causes the issue. To preserve the existing behavior, the cwd…
- Record
GHSA-cj5w-8mjf-r5f8- CVSS 3.1
- 7.4 High
CVSS:3.1/AV:L/AC:H/PR:L/UI:R/S:C/C:L/I:H/A:H - Weakness
- CWE-78
- Updated
- 2026-11-02
NVD
7.4
jupyterlab-git is a JupyterLab extension for version control using Git. On many platforms, a third party can create a Git repository under a name that includes a shell command substitution string in the syntax $(<command>). These directory names are allowed in macOS and a majority of Linux distributions. If a user starts jupyter-lab in a parent directory of this inappropriately-named Git repository, opens it, and clicks "Git > Open Git Repository in Terminal" from the menu bar, then the injected command <command> is run in the user's shell without the user's permission. This issue is occurring because when that menu entry is clicked, jupyterlab-git opens the terminal and runs cd <git-repo-path> through the shell to set the current directory. Doing so runs any command substitution strings present in the directory name, which leads to the command injection issue described here. A previous patch provided an incomplete fix. This vulnerability is fixed in 0.51.1.
- Record
CVE-2025-30370- CVSS 3.1
- 7.4 High
CVSS:3.1/AV:L/AC:H/PR:L/UI:R/S:C/C:L/I:H/A:H - Weakness
- CWE-78
- Updated
- 2026-11-02
OSV
7.4
jupyterlab-git has a command injection vulnerability in "Open Git Repository in Terminal"
jupyterlab-git is a JupyterLab extension for version control using Git. On many platforms, a third party can create a Git repository under a name that includes a shell command substitution string in the syntax $(<command>). These directory names are allowed in macOS and a majority of Linux distributions. If a user starts jupyter-lab in a parent directory of this inappropriately-named Git repository, opens it, and clicks "Git > Open Git Repository in Terminal" from the menu bar, then the injected command <command> is run in the user's shell without the user's permission. This issue is occurring because when that menu entry is clicked, jupyterlab-git opens the terminal and runs cd <git-repo-path> through the shell to set the current directory. Doing so runs any command substitution strings present in the directory name, which leads to the command injection issue described here. A previous patch provided an incomplete fix. This vulnerability is fixed in 0.51.1.
- Record
CVE-2025-30370- CVSS 3.1
- 7.4 High
CVSS:3.1/AV:L/AC:H/PR:L/UI:R/S:C/C:L/I:H/A:H - Weakness
- CWE-78
- Updated
- 2026-11-02
OSVGHSA-cj5w-8mjf-r5f8
7.4
jupyterlab-git has a command injection vulnerability in "Open Git Repository in Terminal"
Overview
On many platforms, a third party can create a Git repository under a name that includes a shell command substitution ^1 string in the syntax $(<command>). These directory names are allowed in macOS and a majority of Linux distributions ^2. If a user starts jupyter-lab in a parent directory of this inappropriately-named Git repository, opens it, and clicks "Git > Open Git Repository in Terminal" from the menu bar, then the injected command <command> is run in the user's shell without the user's permission.
This issue is occurring because when that menu entry is clicked, jupyterlab-git opens the terminal and runs cd <git-repo-path> through the shell to set the current directory ^3. Doing so runs any command substitution strings present in the directory name, which leads to the command injection issue described here. A previous patch provided an incomplete fix ^4.
Scope of Impact
This issue allows for arbitrary code execution via command injection. A wide range of actions are permitted by this issue, including but not limited to: modifying files, exfiltrating data, halting services, or compromising the server's security rules.
We have scanned the source code of jupyterlab-git for other command injection risks, and have not found any at the time of writing.
This issue was reproduced on the latest release of jupyterlab-git, v0.51.0. The steps taken to reproduce this issue are described in the "Proof-of-concept" section below.
Proof-of-concept
-
Create a new directory via
mkdir test/ && cd test/. -
Create a new Git repository under
test/with a command substitution string in the directory name by running these commands:
mkdir '$(touch pwned.txt)'
cd '$(touch pwned.txt)/'
git init
cd ..
- Start JupyterLab from
test/by running jupyter lab. - With JupyterLab open in the browser, double click on
$(touch pwned.txt)in the file browser. - From the top menu bar, click "Git > Open Git Repository in Terminal".
- Verify that
pwned.txtis created undertest/. This demonstrates the command injection issue described here.
Proof-of-concept mitigation
The issue can be mitigated by the patch shown below.
<details><summary>Patch (click to expand)</summary>
diff --git a/src/commandsAndMenu.tsx b/src/commandsAndMenu.tsx
index 3779a6c..71ddcea 100644
--- a/src/commandsAndMenu.tsx
+++ b/src/commandsAndMenu.tsx
@@ -164,31 +164,13 @@ export function addCommands(
label: trans.__('Open Git Repository in Terminal'),
caption: trans.__('Open a New Terminal to the Git Repository'),
execute: async args => {
- const main = (await commands.execute(
- 'terminal:create-new',
- args
- )) as MainAreaWidget<ITerminal.ITerminal>;
+ const cwd = gitModel.pathRepository;
+ const main = (await commands.execute('terminal:create-new', {
+ ...args,
+ cwd
+ })) as MainAreaWidget<ITerminal.ITerminal>;
- try {
- if (gitModel.pathRepository !== null) {
- const terminal = main.content;
- terminal.session.send({
- type: 'stdin',
- content: [
- `cd "${gitModel.pathRepository
- .split('"')
- .join('\\"')
- .split('`')
- .join('\\`')}"\n`
- ]
- });
- }
-
- return main;
- } catch (e) {
- console.error(e);
- main.dispose();
- }
+ return main;
</details>
This patch removes the cd <git-repo-path> shell command that causes the issue. To preserve the existing behavior, the cwd…
- Record
GHSA-cj5w-8mjf-r5f8- CVSS 3.1
- 7.4 High
CVSS:3.1/AV:L/AC:H/PR:L/UI:R/S:C/C:L/I:H/A:H - Weakness
- CWE-78
- Updated
- 2026-11-02
OSVPYSEC-2026-1483
7.4
jupyterlab-git has a command injection vulnerability in "Open Git Repository in Terminal"
Overview
On many platforms, a third party can create a Git repository under a name that includes a shell command substitution ^1 string in the syntax $(<command>). These directory names are allowed in macOS and a majority of Linux distributions ^2. If a user starts jupyter-lab in a parent directory of this inappropriately-named Git repository, opens it, and clicks "Git > Open Git Repository in Terminal" from the menu bar, then the injected command <command> is run in the user's shell without the user's permission.
This issue is occurring because when that menu entry is clicked, jupyterlab-git opens the terminal and runs cd <git-repo-path> through the shell to set the current directory ^3. Doing so runs any command substitution strings present in the directory name, which leads to the command injection issue described here. A previous patch provided an incomplete fix ^4.
Scope of Impact
This issue allows for arbitrary code execution via command injection. A wide range of actions are permitted by this issue, including but not limited to: modifying files, exfiltrating data, halting services, or compromising the server's security rules.
We have scanned the source code of jupyterlab-git for other command injection risks, and have not found any at the time of writing.
This issue was reproduced on the latest release of jupyterlab-git, v0.51.0. The steps taken to reproduce this issue are described in the "Proof-of-concept" section below.
Proof-of-concept
-
Create a new directory via
mkdir test/ && cd test/. -
Create a new Git repository under
test/with a command substitution string in the directory name by running these commands:
mkdir '$(touch pwned.txt)'
cd '$(touch pwned.txt)/'
git init
cd ..
- Start JupyterLab from
test/by running jupyter lab. - With JupyterLab open in the browser, double click on
$(touch pwned.txt)in the file browser. - From the top menu bar, click "Git > Open Git Repository in Terminal".
- Verify that
pwned.txtis created undertest/. This demonstrates the command injection issue described here.
Proof-of-concept mitigation
The issue can be mitigated by the patch shown below.
<details><summary>Patch (click to expand)</summary>
diff --git a/src/commandsAndMenu.tsx b/src/commandsAndMenu.tsx
index 3779a6c..71ddcea 100644
--- a/src/commandsAndMenu.tsx
+++ b/src/commandsAndMenu.tsx
@@ -164,31 +164,13 @@ export function addCommands(
label: trans.__('Open Git Repository in Terminal'),
caption: trans.__('Open a New Terminal to the Git Repository'),
execute: async args => {
- const main = (await commands.execute(
- 'terminal:create-new',
- args
- )) as MainAreaWidget<ITerminal.ITerminal>;
+ const cwd = gitModel.pathRepository;
+ const main = (await commands.execute('terminal:create-new', {
+ ...args,
+ cwd
+ })) as MainAreaWidget<ITerminal.ITerminal>;
- try {
- if (gitModel.pathRepository !== null) {
- const terminal = main.content;
- terminal.session.send({
- type: 'stdin',
- content: [
- `cd "${gitModel.pathRepository
- .split('"')
- .join('\\"')
- .split('`')
- .join('\\`')}"\n`
- ]
- });
- }
-
- return main;
- } catch (e) {
- console.error(e);
- main.dispose();
- }
+ return main;
</details>
This patch removes the cd <git-repo-path> shell command that causes the issue. To preserve the existing behavior, the cwd…
- Record
PYSEC-2026-1483- CVSS 3.1
- 7.4 High
CVSS:3.1/AV:L/AC:H/PR:L/UI:R/S:C/C:L/I:H/A:H - Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
jupyterlab-gitPyPI |
before 0.51.1 | 0.51.1 |
jupyterlab-gitPyPI |
before 0.51.1, plus listed versions 0.1.10.1.20.10.00.10.10.10.1rc0 Show 45 moreShow less0.11.00.11.0rc00.11.0rc10.2.00.2.20.20.00.20.0rc00.21.00.21.0a00.21.0a10.21.0rc00.21.10.22.00.22.10.22.20.22.30.23.00.23.10.23.20.23.30.24.00.3.00.30.00.30.0b10.30.0b20.30.0b30.30.10.31.00.31.0a00.32.00.32.10.32.20.32.30.32.40.33.00.34.00.34.10.34.20.35.00.36.00.37.00.37.10.38.00.39.00.39.1 |
0.51.1 |
History
| Recorded | Changed | Sources |
|---|---|---|
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2025-30370 is a high vulnerability (CVSS 7.4) in Jupyterlab Jupyterlab-git, published April 3, 2025. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.60%, the 48th percentile. Fixed in jupyterlab-git 0.51.1.
References
github.com/jupyterlab/jupyterlab-git/security/advisories/GHSA-cj5w-8mjf-r5f8
github.com/jupyterlab/jupyterlab-git/pull/1196
github.com/jupyterlab/jupyterlab-git/commit/b46482993f76d3a546015c6a94ebed8b77fc2376
github.com/jupyterlab/jupyterlab-git/blob/7eb3b06f0092223bd5494688ec264527bbeb2195/src/commandsAndMenu.tsx
nvd.nist.gov/vuln/detail/CVE-2025-30370
github.com/advisories/GHSA-cj5w-8mjf-r5f8
github.com/CVEProject/cvelistV5/tree/main/cves/2025/30xxx/CVE-2025-30370.json
github.com/jupyterlab/jupyterlab-git
pypi.org/project/jupyterlab-git
Left out here: 26 versions and the rest of 3 source descriptions. The JSON record has them.