gitea project BOPLA Vulnerability Report
Vulnerability 1: POST /{username}/{reponame}/settings/collaboration/access_mode
## Risk Analysis
-
Privilege escalation to repository owner level: a repo admin can elevate themselves to a synthetic owner.
-
Ability to perform owner-only high-risk operations:
- repository transfer
- deletion
- archive / unarchive
- wiki deletion
- cancel transfer
-
This effectively breaks the intended privilege boundary where collaborator permissions should not exceed admin.
## Vulnerability Details
Affected Endpoint:
- POST /{username}/{reponame}/settings/collaboration/access_mode
Core Issue:
- Missing upper-bound constraint on
repository_collaboration.mode
## Verification Details
- Entry Authorization
-
Route group enforces
reqRepoAdmin -
Only requires caller to be repo admin
-
Code:
- routers/web/web.go:1147-1249
- Handler Logic
-
ChangeCollaborationAccessModedirectly converts inputmodetoperm.AccessMode -
No upper-bound validation
-
Code:
- routers/web/repo/setting/collaboration.go:119-128
- Sink Behavior
-
repo_model.ChangeCollaborationAccessModeonly rejects:- mode <= none
- mode > owner
-
mode = owner (4)is accepted -
Direct DB update:
- collaboration.mode
- access.mode
-
Code:
- models/repo/collaboration.go:121-157
- Missing Property Check
-
Missing constraint:
repository_collaboration.mode <= admin
-
Repo admin should not grant owner privilege
- Why Existing Protections Fail
-
Safe path exists:
-
services/repository/AddOrUpdateCollaborator enforces:
- mode < read OR mode > admin → invalid
-
Code:
- services/repository/collaboration.go:21-25
-
-
However:
- Web handler bypasses service layer
-
Frontend restriction exists but is not enforced server-side:
- templates/repo/settings/collaboration.tmpl:22-29
- web_src/js/features/repo-settings.ts:10-31
- Post-Exploitation Effect
-
Permission.IsOwner()defined as:-
AccessMode >= Owner
-
Code:
- models/perm/access/repo_permission.go:38-41
-
-
Multiple sensitive operations rely only on
IsOwner():-
convert, transfer, delete, archive, etc.
-
Code:
- routers/web/repo/setting/setting.go:724-1024
-
-
Result:
- injected owner privilege becomes fully effective
## Security Recommendations
-
Enforce upper-bound constraint at model/service layer:
mode <= admin
-
Ensure all entry points converge to the same validation logic
-
Do not rely on frontend constraints
-
Avoid direct model-level writes without policy enforcement
Vulnerability 2: PUT|DELETE /api/v1/teams/{teamid}/repos/{org}/
## Risk Analysis
-
Organization-level policy bypass:
- repo admin can modify repo-team bindings even when disallowed
-
Breaks governance control over repository access delegation
## Vulnerability Details
Affected Endpoints:
- PUT /api/v1/teams/{teamid}/repos/{org}/
- DELETE /api/v1/teams/{teamid}/repos/{org}/
Core Issues:
-
Missing check on:
organization.repo_admin_change_team_access
-
Unauthorized modification of:
team_repo_rel.repo_id
## Verification Details
- Entry Authorization
-
Requires:
- team member OR org owner OR site admin
-
Additional requirement:
- repo admin access
-
Code:
- routers/api/v1/api.go:487-523
- routers/api/v1/api.go:1666-1685
- routers/api/v1/org/team.go:686-701
- routers/api/v1/org/team.go:738-753
- Reference Safe Path
-
Repo-centric API correctly checks:
!RepoAdminChangeTeamAccess && !IsOwner
-
Code:
- routers/api/v1/repo/teams.go:186-214
-
Web UI path also enforces same logic
-
Code:
- routers/web/repo/setting/collaboration.go:150-217
- Sink Behavior
-
Direct calls:
- TeamAddRepository
- RemoveRepositoryFromTeam
-
DB operations:
- Add:
organization.AddTeamRepo - Remove:
organization.RemoveTeamRepo
- Add:
-
Code:
- services/repository/repo_team.go:19-45
- services/repository/repo_team.go:146-184
- Missing Property Check
-
Missing validation:
organization.repo_admin_change_team_access
-
Intended constraint:
- repo admin cannot modify repo-team bindings unless owner
-
Current logic only checks:
- team membership + repo admin
- Why Existing Protections Fail
-
Service layer does NOT enforce org policy:
- only checks existence conditions
-
Result:
- bypass at entry → sink executes normally
- Post-Exploitation Effect
-
After modification:
RecalculateTeamAccessesis triggered
-
Code:
- services/repository/repo_team.go:43-45
- services/repository/repo_team.go:181-184
-
Result:
- unauthorized bindings become effective immediately
## Security Recommendations
- Enforce
organization.repo_admin_change_team_accessat service layer - Ensure consistent policy validation across all APIs
- Avoid fragmented enforcement across different entry points
Conclusion
- Vulnerability 1: High-risk privilege escalation via missing upper-bound constraint
- Vulnerability 2: Organization policy bypass due to missing sink-side check
Both issues stem from:
- inconsistent enforcement between layers
- missing property-level validation at sink points

浙公网安备 33010602011771号