Severity by source
AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N
PR:L because exploitation requires an authenticated low-privilege token with existing repository membership; C:L because only specific configuration files are exposed, not arbitrary code.
Primary rating from Vendor (https://github.com/go-gitea/gitea).
CVSS VectorVendor: https://github.com/go-gitea/gitea
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N
Lifecycle Timeline
2DescriptionCVE.org
Summary
Three Gitea API endpoints - GET /repos/{owner}/{repo}/issue_templates, GET /repos/{owner}/{repo}/issue_config and GET /repos/{owner}/{repo}/issue_config/validate
- read files from the repository's Code default branch (
.gitea/ISSUE_TEMPLATE/*
and issue_config.yaml) and return their contents, but are registered without the reqRepoReader(unit.TypeCode) authorization middleware that every sibling Code-tree endpoint in the same route group carries.
A user who has access to a private repository through *any single repository unit* (for example an organization team granted only the Issues unit, with no Code access) can therefore read the issue-template and issue-config files of that repository's Code tree, which their permission set should not expose.
---
Root cause
The three endpoints lack the unit guard
routers/api/v1/api.go:1433-1437:
m.Get("/issue_templates", context.ReferencesGitRepo(), repo.GetIssueTemplates) m.Get("/issue_config", context.ReferencesGitRepo(), repo.GetIssueConfig) m.Get("/issue_config/validate", context.ReferencesGitRepo(), repo.ValidateIssueConfig) m.Get("/languages", reqRepoReader(unit.TypeCode), repo.GetLanguages) m.Get("/licenses", reqRepoReader(unit.TypeCode), repo.GetLicenses)
context.ReferencesGitRepo() only opens the git repository - it performs no permission check. Every other endpoint in this group that reads Code-tree content is guarded with reqRepoReader(unit.TypeCode): /languages, /licenses, /contents/*, /file-contents, and /{ball_type:tarball|zipball|bundle}/* (api.go:1418-1445). The three issue-template endpoints are the only Code-tree readers in the group missing that guard.
The enclosing group runs repoAssignment() (api.go:1446), whose access check is satisfied by HasAnyUnitAccessOrPublicAccess - i.e. access to any unit of the repository is sufficient to pass. Without a per-unit reqRepoReader, the handlers run for a caller who has no Code permission.
The handlers return Code-tree file contents
routers/api/v1/repo/repo.go:
func GetIssueTemplates(ctx *context.APIContext) { // :1179 ret := issue.ParseTemplatesFromDefaultBranch(ctx.Repo.Repository, ctx.Repo.GitRepo) ... ctx.JSON(http.StatusOK, ret.IssueTemplates) }
func GetIssueConfig(ctx *context.APIContext) { // :1209 issueConfig, _ := issue.GetTemplateConfigFromDefaultBranch(ctx.Repo.Repository, ctx.Repo.GitRepo) ctx.JSON(http.StatusOK, issueConfig) }
ParseTemplatesFromDefaultBranch / GetTemplateConfigFromDefaultBranch read .gitea/ISSUE_TEMPLATE/* and issue_config.yaml from the default (Code) branch and return them in the JSON response.
---
Proof of Concept
victim-org/private-repo is a private repository. The attacker is a member of an organization team granted access to that repository through a non-Code unit only (e.g. the Issues unit) - a supported Gitea permission configuration.
GET /api/v1/repos/victim-org/private-repo/issue_templates HTTP/1.1 Host: TARGET Authorization: token <attacker token>
The response is 200 OK with the parsed contents of the repository's .gitea/ISSUE_TEMPLATE/* files. The same applies to /issue_config. Because the caller lacks the Code unit, every other Code-tree endpoint (/contents, /languages, …) correctly returns 404/403 for the same token - only these three return data.
---
Impact
A repository collaborator whose granted permissions exclude the Code unit can read the issue-template and issue-config files from the Code default branch of a private repository. The exposure is limited to those specific configuration files (not arbitrary Code-tree content), which is why this is rated low impact. It is nonetheless a unit-level authorization bypass: the endpoints disclose Code-unit content to callers the permission model is meant to exclude.
---
Suggested fix
Add the same unit guard the sibling endpoints use, in routers/api/v1/api.go:
m.Get("/issue_templates", reqRepoReader(unit.TypeCode), context.ReferencesGitRepo(), repo.GetIssueTemplates) m.Get("/issue_config", reqRepoReader(unit.TypeCode), context.ReferencesGitRepo(), repo.GetIssueConfig) m.Get("/issue_config/validate", reqRepoReader(unit.TypeCode), context.ReferencesGitRepo(), repo.ValidateIssueConfig)
(If issue templates are intended to be visible to Issues-unit users for issue creation, reqRepoReader(unit.TypeIssues) is the appropriate guard - but the current absence of any unit guard is the bug.)
---
References
- CWE-862 Missing Authorization
- CWE-284 Improper Access Control
- OWASP A01:2021 Broken Access Control
AnalysisAI
Missing repository-unit authorization on three Gitea API endpoints allows authenticated users with only non-Code unit access (e.g., an Issues-only organization team member) to read .gitea/ISSUE_TEMPLATE/* and issue_config.yaml files from the Code default branch of a private repository. The CVSS score of 4.3 (PR:L, C:L) accurately reflects the narrow scope: exploitation is limited to those specific configuration files, not arbitrary source code. A proof of concept is publicly documented in the vendor advisory (GHSA-3fwp-p5rj-2pxf); no active exploitation is confirmed in the CISA KEV catalog at time of analysis.
Technical ContextAI
Gitea's API router in routers/api/v1/api.go organizes repository endpoints into route groups protected by unit-specific middleware. The reqRepoReader(unit.TypeCode) middleware enforces that the calling user holds Code-unit permission before any Code-tree content is returned. The three affected endpoints - /issue_templates, /issue_config, and /issue_config/validate - were registered with only context.ReferencesGitRepo(), a helper that opens the git repository object but performs no unit-level permission check. The enclosing route group uses repoAssignment(), whose access check passes via HasAnyUnitAccessOrPublicAccess - satisfied by membership through any single unit such as Issues or Wiki - leaving no Code-unit gate on these handlers. The handlers invoke ParseTemplatesFromDefaultBranch and GetTemplateConfigFromDefaultBranch, which read files directly from the default branch of the Code tree and serialize them into the JSON response. Root cause is CWE-862 (Missing Authorization), with the secondary classification of CWE-284 (Improper Access Control) also applicable. The affected package is the Go module code.gitea.io/gitea (CPE: pkg:go/code.gitea.io_gitea). Note: the 'RCE' tag present in the source intelligence is inconsistent with all technical evidence - the CVSS vector, advisory description, and proof of concept all describe information disclosure only; this tag appears to be erroneous and should be disregarded.
RemediationAI
Upgrade Gitea to version 1.26.2, which adds the missing reqRepoReader(unit.TypeCode) middleware to the three affected API endpoints in routers/api/v1/api.go, aligning them with every other Code-tree endpoint in the same route group. Full patch details and advisory are available at https://github.com/go-gitea/gitea/security/advisories/GHSA-3fwp-p5rj-2pxf. Where an immediate upgrade is not feasible, administrators can apply a compensating control at the reverse proxy layer by blocking or rate-limiting access to the URL paths /api/v1/repos/*/issue_templates, /api/v1/repos/*/issue_config, and /api/v1/repos/*/issue_config/validate for tokens not expected to need them; the trade-off is that legitimate Issues-unit users who rely on these endpoints for issue creation UI flows will be impacted. A second option is to audit organization team permission configurations and ensure no sensitive content (infrastructure hints, internal process details) is embedded in issue template files until the patch is deployed.
Broken access control in Gitea's Composer package registry (versions up to and including 1.26.1) lets remote attackers r
Gitea before 1.16.7 does not escape git fetch remote. Rated high severity (CVSS 7.5), this vulnerability is remotely exp
The git hook feature in Gitea 1.1.0 through 1.12.5 might allow for authenticated remote code execution in customer envir
Improper Neutralization of Input During Web Page Generation (XSS or 'Cross-site Scripting') vulnerability in Gitea Gitea
Container escape in Gitea act_runner (Docker backend, through act 0.262.0) lets an authenticated user with workflow-exec
models/repo_mirror.go in Gitea before 1.7.6 and 1.8.x before 1.8-RC3 mishandles mirror repo URL settings, leading to rem
An issue was discovered in Gitea through 1.11.5. Rated high severity (CVSS 7.5), this vulnerability is remotely exploita
Missing Authorization in GitHub repository go-gitea/gitea prior to 1.16.4. Rated high severity (CVSS 7.1), this vulnerab
Open Redirect on login in GitHub repository go-gitea/gitea prior to 1.16.5. Rated medium severity (CVSS 6.1), this vulne
Reverse-proxy authentication bypass in the official Gitea Docker image (versions up to and including 1.26.2) allows any
Branch-protection bypass in Gitea's self-hosted Git server (all versions before 1.26.0) allows a user with push access t
Migration transport protections in Gitea are bypassed for Git LFS operations, affecting all self-hosted instances before
Same weakness CWE-862 – Missing Authorization
View allSame technique Authentication Bypass
View allVendor StatusVendor
SUSE
Severity: Moderate| Product | Status |
|---|---|
| SUSE Linux Enterprise Server 16.1 | Affected |
| SUSE Linux Enterprise Server for SAP applications 16.1 | Affected |
| SUSE Linux Enterprise Module for Package Hub 15 SP5 | Affected |
| SUSE Linux Enterprise Module for Package Hub 15 SP6 | Affected |
| openSUSE Leap 15.5 | Affected |
| openSUSE Leap 15.6 | Affected |
Share
External POC / Exploit Code
Leaving vuln.today
EUVD-2026-41639
GHSA-3fwp-p5rj-2pxf