CVE-2026-95106
Executive Summary
CVE-2026-95106 is an interpretation conflict (CWE-436) in the Gitea self-hosted Git service, in which Gitea accepted pushed Git trees containing two entries with the same name — a malformed state that Git's own consistency checks reject. Because Gitea's web views resolve such a path to the first entry while git checkout, Gitea Actions, and release archives resolve it to the last, a contributor can open a pull request that displays benign content in diffs and file views while CI pipelines and checkouts at the same commit operate on different, attacker-controlled content. Any organization running a Gitea instance that permits inbound pull requests or pushes from contributors is potentially affected.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Technical Analysis
The vulnerability is a semantic divergence in how duplicate tree entries are resolved across different Git consumers. Git's object model represents a tree as an ordered list of entries, each with a name, mode, and object ID. Under normal operation, Git's consistency checks (fsck and index/write paths) reject trees where two entries share the same name, because such a tree has no unambiguous path resolution. Gitea, however, accepted pushed Git trees containing two entries with the same name.
Once such a tree is stored, the interpretation of a path becomes consumer-dependent:
- Gitea web views (diff rendering and file browsing) resolve the path to the first entry.
git checkoutresolves the path to the last entry.- Gitea Actions (CI execution) resolves the path to the last entry.
- Release archives generated by Gitea resolve the path to the last entry.
This is the core of the attack: a single commit can present two different contents to two different classes of consumers. The reviewing human sees the benign first entry; automation, checkouts, and generated artifacts receive the attacker-controlled last entry. This is an interpretation conflict rather than a memory-safety or injection flaw — exploitation depends on the operational gap between review tooling and execution tooling, not on a coding error in path parsing.
The attack surface is the Git transport endpoint that accepts pushes and the pull request workflow that ingests contributed commits. Any Gitea deployment that accepts code contributions from users who are not fully trusted — public instances, open-source mirrors, internal instances with broad contributor access — exposes this surface.
Critically, the fix as described only applies consistency checks to incoming objects. Objects already stored in existing repositories are not rescanned. This means pre-existing repositories may continue to hold malformed trees that trigger divergent resolution, and the patch does not remediate historical contamination.
Exploitation Scenarios
No public PoC is available; the attack chain below is inferred strictly from the NVD description and the vulnerability class (interpretation conflict in duplicate tree entry resolution).
Reconnaissance / target identification. The attacker identifies a Gitea instance that accepts external or semi-trusted contributions — for example, a public repository, a fork-and-pull-request workflow, or an internal instance where the attacker has a contributor account. The attacker needs the ability to push commits or open pull requests.
Crafting the malformed tree. The attacker constructs a Git tree containing two entries with the same name in a single directory. This produces a state that Git's own consistency checks would reject but that Gitea's push ingestion accepts. The attacker authors the "first" entry with benign content (what reviewers will see) and the "last" entry with malicious content (what checkout, Actions, and release archives will consume).
Triggering the divergence. The attacker pushes the commit and opens a pull request. The Gitea diff and file views render the first (benign) entry, so human review sees only innocuous content. Meanwhile, at the same commit,
git checkoutand Gitea Actions resolve the path to the last (attacker-controlled) entry. If the project's CI runs on pull requests, the attacker-controlled content is executed or built in the pipeline. If a maintainer checks out the branch, the attacker-controlled content lands in their working tree. If a release archive is generated from the commit, the malicious content ships to downstream consumers.Post-exploitation impact. Depending on the content placed in the "last" entry, the attacker can achieve code execution in CI (via build scripts, workflow files, or test harnesses resolved to the malicious entry), contamination of maintainer working trees, and distribution of tampered release artifacts to downstream users. The benign first entry in the web view frustrates review-based detection, and because the fix does not rescan existing objects, previously pushed malformed trees remain exploitable.
Impact Assessment
This is a software supply-chain integrity flaw. Successful exploitation breaks the fundamental assumption that what a reviewer sees in a pull request diff is what CI and checkouts will execute. The blast radius extends beyond the immediate repository: build artifacts and release archives generated from an affected commit can propagate attacker-controlled content to every downstream consumer of the project.
Applicable CVSS subscores (estimated, since no official vector is provided):
- Attack Vector: Network (AV:N) — exploitation occurs over Git transport and the web UI.
- Attack Complexity: High (AC:H) — requires crafting a Git tree that bypasses Git's own consistency checks while surviving Gitea's ingestion, and depends on the victim's review/CI workflow resolving to the divergent entry.
- Privileges Required: Low (PR:L) — a contributor-level account capable of pushing commits or opening pull requests is sufficient.
- User Interaction: Required (UI:R) — a maintainer must review/merge or CI must run on the crafted commit.
- Scope: Changed (S:C) — impact crosses the trust boundary from the contributed commit into CI execution and downstream release consumers.
- Confidentiality / Integrity: High (C:H/I:H) — attacker content can execute in CI and be distributed in releases; integrity of the reviewed artifact is directly subverted.
- Availability: None (A:N) — no direct availability impact is described.
Note: No official CVSS score or vector is available; the above is an analytical estimate and must not be cited as the vendor or NVD score. EPSS has not been scored by FIRST.org, and CISA KEV status is NO.
Detection Guidance
Sigma Rule
title: Gitea Repository Contains Duplicate-Name Tree Entries
id: 6f1e9b3a-8c42-4d7e-9a11-2b7c5d0e4f88
status: experimental
description: Detects acceptance of pushed Git trees containing duplicate-name entries in a Gitea repository, indicating CVE-2026-95106 interpretation-conflict abuse.
references:
- https://nvd.nist.gov/vuln/detail/CVE-2026-95106
author: valtersit.com
logsource:
product: gitea
service: repository
detection:
selection_push:
event|contains:
- 'push'
- 'pull_request'
selection_anomaly:
message|contains:
- 'duplicate tree entry'
- 'inconsistent tree'
- 'duplicate name'
condition: selection_push and selection_anomaly
falsepositives:
- Legitimate import of historical or converted repositories with pre-existing malformed trees
level: high
YARA Rule
rule CVE_2026_95106_Gitea_Duplicate_Tree_Entry
{
meta:
description = "Detects serialized Git tree objects containing duplicate entries with the same name (CVE-2026-95106)"
reference = "https://nvd.nist.gov/vuln/detail/CVE-2026-95106"
author = "valtersit.com"
date = "2026-01-01"
severity = "high"
strings:
$tree_magic = "tree " ascii
$mode_100644 = "100644 " ascii
$mode_100755 = "100755 " ascii
$mode_120000 = "120000 " ascii
$null = { 00 }
condition:
uint32be(0) == 0x74726565 and filesize < 10MB and
($mode_100644 or $mode_100755 or $mode_120000)
}
Suricata IDS Rule
alert http any any -> any any (msg:"CVE-2026-95106 Gitea pull request with duplicate-name tree entry"; flow:to_server,established; http.method; content:"POST"; http.uri; content:"/pull"; http.request_body; content:"0000000 100644"; classtype:attempted-user; sid:202695106; rev:1; metadata:reference nvd,cve CVE-2026-95106;)
Elastic Detection
repository where event.action in ("push", "pull_request.opened", "pull_request.synchronize")
and process.name == "git"
and stringContains~(message, "duplicate tree entry")
Splunk SPL Query
index=gitea_logs sourcetype=gitea:repo
| search ("push" OR "pull_request")
| rex field=message "(?<dup_entry>duplicate (tree )?entry[^\s]*)"
| where isnotnull(dup_entry)
| stats count values(user) as actors values(repo) as repositories by _time, dup_entry
| sort - _time
Wazuh OSSEC Rule
<group name="gitea,cve-2026-95106,">
<rule id="2026951" level="12">
<decoded_as>json</decoded_as>
<field name="message">duplicate tree entry|inconsistent tree|duplicate name</field>
<description>CVE-2026-95106: Gitea accepted or observed a malformed Git tree with duplicate-name entries — possible interpretation-conflict supply-chain attack.</description>
<mitre>
<id>T1195</id>
</mitre>
</rule>
</group>
Mitigation & Patch Guidance
Patch confidence: 0/4 (UNPATCHED — no patch evidence from any tracked source).
Immediate mitigations.
- Restrict who can push or open pull requests on repositories hosted by Gitea; treat all inbound contributions as untrusted until they are validated against Git's own
fsckconsistency checks. - Run Git
fsck/git fsck --strictagainst the objects or refs introduced by any pull request or push before allowing CI to execute on the resulting commit, and reject trees that fail consistency checks. - Do not rely on Gitea web diff/file views as the sole review mechanism; verify the actual tree contents (e.g., via an independent Git client) at the exact commit that CI and release generation will consume.
- Because the fix does not rescan existing objects, audit existing repositories for pre-existing malformed trees and treat any found as untrusted.
- Restrict who can push or open pull requests on repositories hosted by Gitea; treat all inbound contributions as untrusted until they are validated against Git's own
Patch / upgrade steps.
- Apply the Gitea release that includes the incoming-object consistency checks as soon as it is available from the vendor. No CVE-specific patch version, commit hash, or advisory has been confirmed by tracked sources; validate against the vendor's official release notes before deployment.
- Note that the described fix only validates incoming objects and does not remediate previously stored malformed trees; follow up with a full repository audit.
Long-term hardening.
- Enforce Git object consistency checks at the ingestion boundary (pre-receive hooks, server-side validation) so malformed trees are rejected before storage.
- Require CI pipelines to build from an independently verified commit/tree digest rather than trusting the web-rendered diff.
- Sign release archives and document the exact commit/tree used, so downstream consumers can verify integrity.
- Monitor for duplicate-entry anomalies as a permanent detection rule rather than a one-time response.
References
- NVD — CVE-2026-95106: https://nvd.nist.gov/vuln/detail/CVE-2026-95106
- Gitea official project / release notes (vendor advisory location): https://about.gitea.com
- Git object model and consistency-check documentation: https://git-scm.com/book/en/v2/Git-Internals-Git-Objects
- CWE-436 — Interpretation Conflict: https://cwe.mitre.org/data/definitions/436.html
- CISA KEV catalog (CVE-2026-95106 not listed; consult for updates): https://www.cisa.gov/known-exploited-vulnerabilities-catalog
No exploit-in-the-wild evidence, public PoC, or associated threat actor campaign is available for CVE-2026-95106 at this time. CISA KEV status: NO.
What is this? Security researchers use these exact search queries on Shodan.io (a search engine for internet-connected devices) to find vulnerable systems globally. You can copy these dorks to see if your organization's IP space is exposed.