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

  1. Entry Authorization
  • Route group enforces reqRepoAdmin

  • Only requires caller to be repo admin

  • Code:

    • routers/web/web.go:1147-1249
  1. Handler Logic
  • ChangeCollaborationAccessMode directly converts input mode to perm.AccessMode

  • No upper-bound validation

  • Code:

    • routers/web/repo/setting/collaboration.go:119-128
  1. Sink Behavior
  • repo_model.ChangeCollaborationAccessMode only rejects:

    • mode <= none
    • mode > owner
  • mode = owner (4) is accepted

  • Direct DB update:

    • collaboration.mode
    • access.mode
  • Code:

    • models/repo/collaboration.go:121-157
  1. Missing Property Check
  • Missing constraint:

    • repository_collaboration.mode <= admin
  • Repo admin should not grant owner privilege

  1. 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
  1. 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

  1. 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

  1. 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

  1. Sink Behavior
  • Direct calls:

    • TeamAddRepository
    • RemoveRepositoryFromTeam
  • DB operations:

    • Add: organization.AddTeamRepo
    • Remove: organization.RemoveTeamRepo
  • Code:

    • services/repository/repo_team.go:19-45
    • services/repository/repo_team.go:146-184

  1. 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

  1. Why Existing Protections Fail
  • Service layer does NOT enforce org policy:

    • only checks existence conditions
  • Result:

    • bypass at entry → sink executes normally

  1. Post-Exploitation Effect
  • After modification:

    • RecalculateTeamAccesses is 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_access at 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
posted @ 2026-05-06 09:13  Aibot  阅读(18)  评论(0)    收藏  举报