GHSA-3r5c-2xxx-h872 CVE-2026-58511 GO-2026-6040
Gitea: Webhook Authorization Header Returned in Plaintext via API
- Severity
- 2.7 / 10
- Low · CVSS 3.1
- Exploit chance (EPSS)
- 0.39%
- Chance of exploitation in the next 30 days. Higher than 32.76% of scored vulnerabilities.
- Known exploited
- No
- Not in CISA's catalog
- Weakness
- CWE-200 Exposure of Sensitive Information to an Unauthorized Actor
- Fix
- Available
- 2 packages have a fixed version
Description
Summary
The ToHook() function in services/webhook/general.go decrypts the webhook's HeaderAuthorizationEncrypted field and returns the plaintext authorization header in the API response. Any repository admin can read the full plaintext value of webhook authorization headers (Bearer tokens, Basic auth credentials, API keys) set by other admins.
The authorization header is stored encrypted in the database using the server's SecretKey, but ToHook() decrypts it before serializing it into the API response — converting a write-only secret into a readable credential.
Vulnerable Code
File: services/webhook/general.go:407-420
func ToHook(repoLink string, w *webhook_model.Webhook) (*api.Hook, error) {
// ...
authorizationHeader, err := w.HeaderAuthorization() // DECRYPTS from DB
if err != nil {
return nil, err
}
return &api.Hook{
// ...
AuthorizationHeader: authorizationHeader, // PLAINTEXT in response
// ...
}, nil
}
Decryption function: models/webhook/webhook.go:209-216
func (w Webhook) HeaderAuthorization() (string, error) {
if w.HeaderAuthorizationEncrypted == "" {
return "", nil
}
return secret.DecryptSecret(setting.SecretKey, w.HeaderAuthorizationEncrypted)
}
Affected Endpoints
All call ToHook():
GET /api/v1/repos/{owner}/{repo}/hooks(requires repo admin)GET /api/v1/repos/{owner}/{repo}/hooks/{id}(requires repo admin)GET /api/v1/admin/hooks(requires site admin)GET /api/v1/orgs/{org}/hooks(requires org admin)GET /api/v1/user/hooks(requires authenticated user)
Steps to Reproduce
- Admin A creates a webhook with a sensitive authorization header.
- Admin B (different repo admin) lists webhooks via
GET /api/v1/repos/{owner}/{repo}/hooks. - The API response includes the full plaintext authorization header set by Admin A.
Impact
- Cross-admin secret exposure on shared repositories
- Credential harvesting if a repo admin's Gitea token is stolen
- External service compromise via leaked Bearer tokens and API keys
- Undermines the intentional encryption-at-rest protection
Suggested Fix
The authorization header should be write-only. Return a masked/redacted version or a boolean has_authorization_header flag instead.
References
- Vulnerable function:
services/webhook/general.go:392-425 - Decryption function:
models/webhook/webhook.go:209-216 - Verified against commit 19f0169
Affected versions
Go
| Package | Vulnerable | Fixed in |
|---|---|---|
| code.gitea.io/gitea | < 1.27.0 |
1.27.0 |
| gitea.dev | < 1.27.0 |
1.27.0 |
How to fix
Move to the fixed version or later with your package manager, update the lockfile, and run your tests. If the package only arrives through another dependency, upgrade that dependency first. If none of its releases pulls a fixed version yet, force the version with your package manager's override.
code.gitea.io/gitea Go → 1.27.0
- go
go get code.gitea.io/gitea@v1.27.0 && go mod tidy
gitea.dev Go → 1.27.0
- go
go get gitea.dev@v1.27.0 && go mod tidy
Severity breakdown
CVSS 3.1 2.7
CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:L/I:N/A:N
- Attack vector
- Network
- Attack complexity
- Low
- Privileges required
- High
- User interaction
- None
- Scope
- Unchanged
- Confidentiality
- Low
- Integrity
- None
- Availability
- None
Weakness
CWE-200: Exposure of Sensitive Information to an Unauthorized Actor
The product exposes sensitive information to an actor that is not explicitly authorized to have access to that information.
How to prevent it
- Architecture and Design: Compartmentalize the system to have "safe" areas where trust boundaries can be unambiguously drawn. Do not allow sensitive data to go outside of the trust boundary and always be careful when interfacing with a compartment outside of the safe area. Ensure that appropriate compartmentalization is built into the system design, and the compartmentalization allows for and reinforces privilege separation functionality. Architects and designers should rely on the principle of least privilege to decide the appropriate time to use privileges and the time to drop privileges.
References
Packages
Other links
Timeline
- Published
- Last updated by the source
- Latest EPSS score
Related advisories
| Advisory | Severity | Why it's related |
|---|---|---|
| GHSA-rcr6-4jqh-j84m Gitea: Remote Code Execution via diffpatch Git Hook Installation | Critical Known exploited | Also affects code.gitea.io/gitea |
| GHSA-fq2p-5p22-8g6j Gitea: Public-Only Personal access tokens scope bypass in Organization and Permission Endpoints | Medium | Also affects code.gitea.io/gitea |
| GHSA-2wm4-vwp6-v7xc Gitea: SSRF via Migration Asset Downloads Bypasses hostmatcher — Reads Internal Files and Cloud Metadata | High | Also affects code.gitea.io/gitea |
| GHSA-frpw-3h2q-4jj6 Gitea: Cross-Repo Information Disclosure via Org-Level Actions Run/Job APIs | Medium | Also affects code.gitea.io/gitea |
| GHSA-q423-49rw-g9mh Gitea: GHSA-8fwc-qjw5-rvgp ClearRepoWatches fix not applied to API EditRepo path — sister code path retains stale watches on public->private | Medium | Also affects code.gitea.io/gitea |
| GHSA-h56g-4qw7-2mxg Gitea: Public-only API token restriction is not enforced on team API routes | Medium | Also affects gitea.dev |
| GHSA-prr9-9mp4-5gp2 Gitea: Private org member list leaked via /members API endpoint — incomplete fix for PR #38145 | High | Also affects gitea.dev |
| GHSA-2fcr-jfvc-vgg2 Gitea: Two SSRF findings | High | Also affects code.gitea.io/gitea |
MergeHarbor checks every repository's dependencies against this database, ranks what matters by exploitability and reachability, routes it to the owning team and opens the fix pull request.
Check your repos with MergeHarbor