GitHub Security Advisory: GHSA-rjv5-9px2-fqw6
Package: gogs.io/gogs (GO)
Severity: MODERATE (CVSS 0.0)
CWE: CWE-284: Improper Access Control
Vulnerable versions: <= 0.13.3
Patched in: 0.13.4

Summary: Gogs has authorization bypass in repository deletion API

Details:
### Summary

The DELETE /api/v1/repos/:owner/:repo endpoint lacks necessary permission validation middleware. Consequently, any user with read access (including read-only collaborators) can delete the entire repository.

This vulnerability stems from the API route configuration only utilizing the repoAssignment() middleware (which only verifies read access) without enforcing reqRepoOwner() or reqRepoAdmin().

### Details
0. vulnerability location:

- Vulnerable Endpoint：DELETE /api/v1/repos/:owner/:repo
- Routing configuration file: internal/route/api/v1/api.go (approximately line 253)
- Function handling file: internal/route/api/v1/repo/repo.go (approximately lines 320-338)

1. Root Cause Analysis

Code Location 1: API Route Configuration (internal/route/api/v1/api.go ~ line 253)

```go
// 当前的路由配置（存在漏洞）
m.Delete("", repo.Delete)  // 仅继承了外层的 repoAssignment() 中间件
```

Code Location 2: Delete Function Implementation (internal/route/api/v1/repo/repo.go ~ lines 320-338)
```go
// Delete 函数内部没有额外的权限检查
func Delete(c *context.APIContext) {
    // 直接执行删除操作，未验证用户是否为所有者
    if err := models.DeleteRepository(c.User.ID, c.Repo.Repository.ID); err != nil {
        c.Error(500, "DeleteRepository", err)
        return
    }
    c.Status(204)
}
```

2. Missing Permission Check
Comparison with route configurations for other sensitive operations:

```go
// Webhooks 管理（正确实现）
m.Group("/hooks", func() {
    m.Combo("").
        Get(repo.ListHooks).
        Post(bind(api.CreateHookOption{}), repo.CreateHook)
}, reqRepoAdmin())  // ✅ 使用了权限中间件

// 部署密钥管理（正确实现）
m.Group("/keys", func() {
    m.Combo("").
        Get(repo.ListDeployKeys).
        Post(bind(api.CreateKeyOption{}), repo.CreateDeployKey)
}, reqRepoAdmin())  // ✅ 使用了权限中间件

// 删除仓库（漏洞）
m.Delete("", repo.Delete)  // ❌ 没有使用权限中间件
```
3. Data Flow Path

- API Request Path: DELETE /api/v1/repos/:owner/:repo
- Route Handling: The outer middleware repoAssignment() verifies that the user has read access (Passed).
- Execution: The system directly executes the repo.Delete() function.
- Permission Check: The reqRepoOwner() middleware check is missing.
- Internal Validation: There is no permission validation inside the Delete() function either.
- Result: Any user with read permission can delete the repository.


### PoC

Prerequisites

- A running Gogs instance.
- The attacker's account is added as a collaborator to the target repository (Read access is sufficient).
- The attacker possesses a valid API access token.
- The target repository exists and is accessible.

📜 Test Steps (Bash)

1. Verify Gogs service is running
curl -I http://localhost:10880

2. Create test accounts and repository
- Owner account: owner / owner123456
- Read-only account: victim / victim123456
- Test repository: owner/delete-test
<img width="1580" height="832" alt="image" src="https://github.com/user-attachments/assets/d1babac8-d952-4765-ba34-d4891c12b8db" />


3. Add 'victim' as a read-only collaborator
Perform this via the Web UI or API
<img width