CVE-2026-66877
Executive Summary
CVE-2026-66877 is an authorization bypass flaw in Gitea's continuous integration integration (Gitea Actions) that undermines the first-time fork contributor approval gate designed to prevent unreviewed workflow code from executing. While Gitea blocks jobs directly, some job transition and dispatch paths fail to re-check a run's approval requirement, allowing an attacker to use a separate run sharing a job-level concurrency group to cancel a pending job — causing blocked sibling jobs to be re-emitted and dispatched without approval. Any Gitea instance hosting public or multi-tenant repositories with Gitea Actions and self-hosted runners is affected, and successful exploitation grants high confidentiality and integrity impact within the runner context, though fork secrets remain withheld and the run token remains read-only.
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
CVE-2026-66877 exploits Gitea's enforcement of the "first-time fork contributor approval" control. Gitea normally refuses to schedule workflow jobs originating from a first-time fork contributor until a maintainer approves the associated run. The NVD description states this control is enforced by blocking jobs, but that "some job transition and dispatch paths do not re-check the run's approval requirement." This is a classic case of inconsistent authorization enforcement across code paths — the approval decision is validated at one layer (initial job blocking) but not re-validated at the transition/re-dispatch layer.
The mechanism leverages a shared job-level concurrency group. Gitea Actions supports concurrency groups that serialize or cancel overlapping jobs. When two separate runs share the same job-level concurrency group, one run can cancel a pending job belonging to the approval-gated run. The described defect is that cancellation of a pending job triggers re-emission and dispatch of its "blocked sibling jobs" — and those sibling jobs are dispatched without the approval check being applied on the re-emission path. The net effect: unreviewed workflow code that should have remained blocked executes.
The root cause is CWE-284 (Improper Access Control) — the approval requirement is not carried through, or re-verified, at every point where a job can transition state or be re-dispatched. The concurrency-group cancellation is the trigger that drives execution down an unguarded path. Gitea's defense-in-depth limits the impact: fork secrets remain withheld, and the run token remains read-only. However, execution occurs on self-hosted runners, which is significant because self-hosted runners frequently have greater network reach into internal infrastructure than ephemeral hosted runners, and the code runs with whatever OS-level privileges the runner process holds.
Because the CVSS vector is AV:N/AC:L/PR:L/UI:N, exploitation requires only a low-privileged authenticated account on the target Gitea instance (sufficient to open a fork and submit a workflow), no user interaction, and low attack complexity. No public proof-of-concept, exploit code, or Nuclei template is known to exist at time of writing; the attack chain below is therefore inferred from the vulnerability class (improper access control across job state transitions) rather than from a published exploit.
Affected version ranges are not enumerated by any tracked source. Administrators must self-assess against their deployed Gitea version, since no vendor patch or fixed-version reference is available.
Exploitation Scenarios
Given the absence of a public PoC, the following chain is inferred strictly from the behavior described in the NVD description and the vulnerability class (authorization bypass via inconsistent enforcement of an approval requirement across job transition and dispatch paths).
Reconnaissance / target identification. The attacker identifies a Gitea instance hosting a public or multi-tenant repository that uses Gitea Actions with at least one self-hosted runner. The attacker confirms that first-time fork contributor approval is enabled (the repository accepts fork-based pull request workflows, which is precisely the condition the approval gate is designed for), and enumerates repositories where a target workflow triggers on fork-sourced events.
Establishing the precondition. The attacker registers or uses a low-privileged account (PR:L) and creates a fork of the target repository. As a first-time fork contributor, the attacker's workflow submission causes a run to be created whose jobs are held/blocked by the approval requirement.
Triggering the specific flaw. The attacker arranges for a separate run to share the same job-level concurrency group as the approval-gated run. Per the description, this separate run can cancel the pending job of the gated run. The critical defect is that when the pending job is cancelled, the gated run's "blocked sibling jobs" are re-emitted and dispatched, and the transition/dispatch path does not re-check the run's approval requirement.
Payload / execution method (vulnerability-class level). The re-emitted sibling jobs execute the attacker-supplied workflow code on the self-hosted runner without maintainer approval. At the vulnerability-class level, this is arbitrary workflow code execution on the runner host — the attacker controls the steps defined in the unreviewed workflow. No specific step names, action references, or API endpoints are asserted here because none are given in the description.
Post-exploitation impact. The unreviewed code runs on the self-hosted runner. Per the description, fork secrets remain withheld and the run token remains read-only; therefore exfiltration of repository secrets and write operations via the token are not expected directly. The meaningful impact is that attacker-controlled code executes inside the runner's environment — which may expose the runner's filesystem, environment variables unrelated to fork secrets, and network-reachable internal services, consistent with the CVSS C:H/I:H subscores. Lateral movement toward internal infrastructure reachable from a self-hosted runner is the principal downstream risk.
Impact Assessment
CVSS:3.1 base score 8.1 (High) with vector CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N. Each subscores as follows:
- AV:N (Network) — the Gitea web/API surface is remotely reachable.
- AC:L (Low) — no special conditions beyond sharing a job-level concurrency group are described as prerequisites.
- PR:L (Low) — a low-privileged authenticated account capable of forking and submitting workflows suffices.
- UI:N (None) — no maintainer interaction is required; in fact the attack deliberately avoids the approval step.
- S:U (Unchanged) — impact is scoped to the vulnerable runner/agent component; the Gitea server itself is not described as compromised.
- C:H / I:H — attacker code executes with read and write access in the runner's environment, giving high confidentiality and integrity impact within that scope.
- A:N (None) — no availability impact is described.
Blast radius: every Gitea deployment that (a) allows fork-based contributions, (b) uses Gitea Actions, and (c) attaches at least one self-hosted runner. Self-hosted runners are the highest-value target because they typically sit inside trusted network segments and may hold ambient credentials and network routes unavailable to external hosts. Organizational impact centers on supply-chain integrity: unreviewed code executing in the build pipeline can tamper with build outputs and reach internal systems. The mitigations noted in the description (fork secrets withheld, read-only run token) reduce but do not eliminate risk — the execution itself is the exposure.
No CISA KEV listing exists, and there is no evidence of exploit-in-the-wild at the time of writing.
Detection Guidance
Sigma Rule
title: Gitea Actions Approval Bypass via Concurrency Group Job Cancellation
id: 7c2f1a94-3b6e-4d1a-9f2c-gitea66877001
status: experimental
description: Detects Gitea Actions job cancellation within a job-level concurrency group
that results in blocked sibling jobs being re-emitted and dispatched without approval
(CVE-2026-66877 authorization bypass).
references:
- https://nvd.nist.gov/vuln/detail/CVE-2026-66877
author: valtersit.com
date: 2026/01/01
logsource:
product: gitea
service: actions
detection:
selection_cancel:
action|contains:
- 'concurrency'
- 'cancel'
selection_run:
event|contains: 'workflow_run'
selection_approval_bypass:
- 'job_status: re-emitted'
- 'approval_required: false'
- 'dispatch_without_approval: true'
condition: (selection_cancel and selection_run) or selection_approval_bypass
falsepositives:
- Legitimate maintainer-triggered concurrency cancellations
- Expected concurrency serialization in trusted branches
level: high
tags:
- attack.t1190
- attack.t1078
YARA Rule
rule CVE_2026_66877_Gitea_Actions_Approval_Bypass
{
meta:
description = "Detects Gitea Actions workflow content and log markers consistent with approval bypass via concurrency group job cancellation (CVE-2026-66877)"
reference = "https://nvd.nist.gov/vuln/detail/CVE-2026-66877"
author = "valtersit.com"
date = "2026-01-01"
severity = "high"
strings:
$g1 = "concurrency" ascii nocase
$g2 = "cancel-in-progress" ascii nocase
$g3 = "Gitea Actions" ascii nocase
$g4 = "first-time contributor" ascii nocase
$g5 = "approval" ascii nocase
$r1 = "re-emitted" ascii nocase
$r2 = "dispatch" ascii nocase
$r3 = "withheld" ascii nocase
$w1 = "workflow_run" ascii nocase
$w2 = "self-hosted" ascii nocase
$flow1 = "on:" ascii
$flow2 = "jobs:" ascii
condition:
(uint32(0) == 0x46494741 or $g3 or ($flow1 and $flow2)) and
($g1 and $g2) and
($g4 or $g5 or $r1 or $r2) and
($w1 or $w2 or $r3)
}
Suricata IDS Rule
alert http any any -> any any (msg:"CVE-2026-66877 Gitea Actions Approval Bypass Attempt via Concurrency Cancel and Dispatch"; flow:established,to_server; http.method; content:"POST"; http.uri; content:"/api/v1/repos/"; http.uri; content:"/actions"; http.request_body; content:"concurrency"; http.request_body; content:"cancel"; http.request_body; content:"dispatch"; classtype:attempted-admin; reference:cve,CVE-2026-66877; reference:url,nvd.nist.gov/vuln/detail/CVE-2026-66877; sid:6687701; rev:1; metadata:service http, policy balanced-ips drop, policy security-ips drop;)
Elastic Detection
sequence by user.name, host.name with maxspan=10m
[ any where event.category == "web" and
url.path : "/api/v1/repos/*/actions*" and
http.request.method == "POST" and
http.request.body.content : "*concurrency*" and
http.request.body.content : "*cancel*" ]
[ any where event.category in ("process", "web") and
(process.name : "act_runner" or process.command_line : "*gitea*runner*" or
message : "*workflow_run*" and message : "*dispatched*") and
not event.action : "approval_granted" ]
Splunk SPL Query
index=gitea sourcetype=gitea:actions OR sourcetype=gitea:server
(concurrency_group=* OR event=*workflow_run* OR "cancel-in-progress")
(dispatch=* OR "re-emitted" OR "job_dispatched" OR status=dispatched)
(NOT approval=* OR approval="false" OR approval="pending")
| stats count min(_time) as first_seen max(_time) as last_seen
values(action) as actions values(concurrency_group) as concurrency_groups
by user, repo, run_id
| where count > 1
| convert ctime(first_seen) ctime(last_seen)
| sort - count
Wazuh OSSEC Rule
<group name="gitea,web,cve-2026-66877,">
<rule id="668771" level="10">
<decoded_as>json</decoded_as>
<field name="event">\.+</field>
<match>workflow_run|cancel-in-progress|concurrency</match>
<description>CVE-2026-66877: Gitea Actions concurrency cancellation or workflow run activity detected</description>
<mitre>
<id>T1190</id>
</mitre>
<group>gitea_actions,</group>
</rule>
<rule id="668772" level="12">
<if_sid>668771</if_sid>
<match>dispatched|re-emitted|without approval</match>
<description>CVE-2026-66877: Gitea Actions job dispatched without approval after concurrency cancellation - possible authorization bypass</description>
<mitre>
<id>T1190</id>
<id>T1078</id>
</mitre>
<group>gitea_actions,</group>
</rule>
</group>
Mitigation & Patch Guidance
Patch confidence: 0/4 (UNPATCHED — no patch evidence from any tracked source). No vendor fix, fixed version, or workaround is currently published by any tracked source. The following are defensive recommendations based on the vulnerability class; they are not vendor-supplied fixes.
1) Immediate mitigations
- Disable Gitea Actions on repositories that accept fork-based contributions where self-hosted runners are attached, until an audit of job transition/dispatch paths is complete.
- Restrict who can trigger concurrency-group cancellation, or avoid sharing job-level concurrency groups between approval-gated runs and runs controllable by low-privileged fork contributors. Where concurrency groups are required, scope them so that an unapproved run cannot share a group with a trusted run.
- Require approval for all fork-sourced workflow runs rather than only first-time contributors, removing the reliance on the first-time-contributor gate that this CVE circumvents.
- Isolate self-hosted runners: run them in dedicated, network-restricted segments so that any code that does execute has minimal reach to internal services, and ensure they hold no ambient credentials beyond the read-only run token.
2) Patch / upgrade steps
- No patch is currently available from any tracked source. Monitor the Gitea project's security advisories and release notes for a fixed version; there are currently no affected-version ranges enumerated, so determine your exposure by self-assessment.
- Once a fixed release is published, upgrade immediately and re-verify that approval requirements are enforced across job cancellation, transition, and dispatch paths.
3) Long-term hardening
- Adopt a "re-check at every state transition" authorization model for build systems: any job cancellation, re-emission, or dispatch must independently re-validate the originating run's approval state.
- Treat fork-submitted workflows as fully untrusted input; require explicit maintainer approval for every external run and log all approval-bypass-relevant state transitions.
- Apply least privilege to runners and monitor for unexpected runner-to-internal-network traffic.
- Track CVE-2026-66877 in your vulnerability management platform; because it is unpatched and has no KEV listing, compensate with the mitigations above while awaiting a fix.
References
- NVD — CVE-2026-66877: https://nvd.nist.gov/vuln/detail/CVE-2026-66877
- MITRE CWE-284 — Improper Access Control: https://cwe.mitre.org/data/definitions/284.html
- Gitea project security advisories and release notes: https://github.com/go-gitea/gitea/security/advisories
- Gitea Actions documentation (concurrency and approval controls): https://docs.gitea.com/usage/actions/overview
- CISA Known Exploited Vulnerabilities catalog (verify CVE-2026-66877 is not listed): https://www.cisa.gov/known-exploited-vulnerabilities-catalog
No public PoC, exploit code, Nuclei template, or exploit-in-the-wild activity is currently known for CVE-2026-66877. The vulnerability is not listed in CISA KEV. No threat actor campaigns have been attributed at the time of writing.
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.