VDB
EN
HIGH

GHSA-g9g6-qhrc-p3qc

Gitea: Improper authorization on OAuth sign-in callback silently re-enables administrator-disabled accounts

빠른 조치

GHSA-g9g6-qhrc-p3qc — code.gitea.io/gitea: 아래 명령으로 수정 버전으로 올리세요.

go get code.gitea.io/gitea@v1.26.4

상세

### Summary

The OAuth2 sign-in callback in Gitea 1.26.1 unconditionally re-enables a locally-disabled account whenever the user authenticates through a linked external identity provider, silently undoing any administrator-initiated `Disable Account` action and issuing a fresh authenticated session in the same response. Once a user has linked any external IdP, the administrator's disable toggle becomes non-binding — the user can re-enable themselves on demand by completing one OAuth callback, regaining full read and write access to their repositories, organizations, and access tokens.

### Details

Improper Authorization is present on the `code` and `state` parameters of the `/user/oauth2/{source-name}/callback` endpoint in Gitea version 1.26.1. The handler `routers/web/auth/oauth.go::handleOAuth2SignIn` reads the local user's `IsActive` flag at lines 350-352 and, when it is `false`, sets `opts.IsActive = optional.Some(true)` before calling `user_service.UpdateUser` and immediately establishing a session. The active-state precondition that the request middleware `routers/web/web.go::verifyAuthWithOptions` enforces for every other request is therefore evaluated against the freshly-flipped row on the next request, so a site administrator's "disable user" action is silently undone the next time the user authenticates through any linked external identity provider.

The root cause is that the callback path treats the local `IsActive` flag as stale bookkeeping to reconcile against the external identity, rather than as an authoritative administrative override. The local-credential sign-in path correctly renders `IsErrUserInactive` in the same condition; only the OAuth callback path flips the flag and proceeds.

### PoC

1. As a site administrator, configure an OAuth2 authentication source via `Site Administration -> Authentication Sources -> Add Authentication Source`. Any external provider works (a self-hosted Keycloak, an upstream Gitea acting as OIDC, GitHub, GitLab, Microsoft, Google). 2. Have a normal user (`alice` in the example) sign in through that source at least once. The callback creates the row in `external_login_user` linking alice's local account to the IdP identity. 3. As the site administrator, disable alice's account: `Site Administration -> User Accounts -> alice -> "Disable Account"`. Confirm the flag is set with the admin API.

#### HTTP REQUEST

```http GET /api/v1/admin/users/alice HTTP/1.1 Host: <HOST> Authorization: token <ADMIN_TOKEN> Accept: application/json ```

#### HTTP RESPONSE

```http HTTP/1.1 200 OK Content-Type: application/json;charset=utf-8

{"id":2,"login":"alice","active":false,...} ```

4. Have alice click "Sign in with <source-name>" on the Gitea login page and complete the OAuth dance with the IdP. The callback handler runs, observes `IsActive=false`, sets `opts.IsActive=true`, calls `UpdateUser`, and issues a session on the same response. Alice lands on `/`. 5. Re-read the same admin API endpoint and observe that `active` has flipped back to `true` without administrator action.

#### HTTP REQUEST

```http GET /api/v1/admin/users/alice HTTP/1.1 Host: <HOST> Authorization: token <ADMIN_TOKEN> Accept: application/json ```

#### HTTP RESPONSE

```http HTTP/1.1 200 OK Content-Type: application/json;charset=utf-8

{"id":2,"login":"alice","active":true,...} ```

### Impact

Once a user has linked any external identity provider, the site administrator's "disable user" toggle becomes non-binding on that account: the user can re-enable themselves on demand by completing one OAuth callback, regaining full read and write access to their repositories, organizations, and tokens. In SSO-fronted Gitea deployments where the disable toggle is the documented incident-response action for compromised accounts or departed employees, this defeats the only short-term remediation available before the identity provider can revoke the underlying federated identity.

이 버전이 영향받나요?

사용 중인 패키지 버전을 입력하면 즉시 평가합니다.

영향 패키지

Go / code.gitea.io/gitea
최초 영향 버전: 0 수정 버전: 1.26.4
수정 go get code.gitea.io/gitea@v1.26.4

참고