Description
Gitea Version
Gitea version 1.16.3 built with GNU Make 4.1, go1.17.7 : bindata, sqlite, sqlite_unlock_notify
Git Version
2.25.1
Operating System
Ubuntu 20.04
How are you running Gitea?
Installed with:
# mkdir
# useradd -m -r -d /srv/gitea gitea
# curl -L https://github.com/go-gitea/gitea/releases/download/v1.16.3/gitea-1.16.3-linux-amd64 -o /srv/gitea/gitea
# chmod +x /srv/gitea/gitea
Run manually with:
# sudo -i gitea
# ./gitea
On:
# cat /etc/os-release
NAME="Ubuntu"
VERSION="20.04.4 LTS (Focal Fossa)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 20.04.4 LTS"
VERSION_ID="20.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=focal
UBUNTU_CODENAME=focal
(and I have an nginx reverse proxy for TLS in front; if you want to see it's config too I can add it)
Database
PostgreSQL
Can you reproduce the bug on the Gitea demo site?
Yes
Log Gist
https://gist.github.com/kousu/7a0adf177e50bf8387a00b4fa3fd7dd3
Description
An OAuth app created by a deleted user is left behind in the database, and tokens it handed out are still valid, and can even see private repos created after the deletion.
Reproduction
-
Make two accounts
-
In account 1: create an OAuth app
-
In account 2: create a couple repositories
You can see this on the demo site at: https://try.gitea.io/bivott82
-
Deploy DroneCI (or some other OAuth consumer), providing it the OAuth app credentials.
Get a public IP, set up DNS and open firewall ports for :80 and :443, and install docker before running this:
docker run \ --volume=/var/lib/drone:/data \ --env=DRONE_GITEA_SERVER=https://try.gitea.io \ --env=DRONE_GITEA_CLIENT_ID=4d9b78ea-d8fc-45ed-a11a-ea684a690108 \ --env=DRONE_GITEA_CLIENT_SECRET=gto_z5tbfeunl4g752hlj5aeoksj25jev7lxblzejdop5sxt76nmacvq \ --env=DRONE_RPC_SECRET="$(openssl rand -hex 16)" \ --env=DRONE_SERVER_HOST=drone1.kousu.ca \ --env=DRONE_SERVER_PROTO=https \ --env=DRONE_TLS_AUTOCERT=true \ --publish=80:80 \ --publish=443:443 \ --restart=always \ --detach=true \ --name=drone \ drone/drone:2
-
In account 2: login to DroneCI; you will see the two repositories:
-
In account 1: delete account
-
In account 1: create a third repository
You can see this on the demo site at: https://try.gitea.io/bivott82
-
In DroneCI: refresh
You will: incorrectly see the third repository.
-
Log out of DroneCI
-
Try to login again:
You will: get a half-correct HTTP 500 error from Gitea.
You should be able to see this screen on the demo site at:
https://try.gitea.io/login/oauth/authorize?client_id=4d9b78ea-d8fc-45ed-a11a-ea684a690108&redirect_uri=https%3A%2F%2Fdrone1.kousu.ca%2Flogin&response_type=code&state=30b95ff183c471d4 -
If you can look in the database:
You will: see the
oauth2_application
is still recorded.# sudo -u gitea psql -c 'select * from oauth2_application' | tee /dev/null id | uid | name | client_id | client_secret | redirect_uris | created_unix | updated_unix ----+-----+---------+--------------------------------------+--------------------------------------------------------------+------------------------------------+--------------+-------------- 1 | 5 | DroneCI | 3cb8ec3b-5140-4875-bffa-716f9cf1cef7 | $2a$10$L6nyevnaNwKNB3cZc6rhUenodOlZ2DNFr4wIM.jPIP9BULRHRP8QW | ["http://3.98.145.180:8080/login"] | 1647449740 | 1647452962 (1 row)
even though the associated
uid
is gone:# sudo -u gitea psql -c 'select id,name from public.user where id=5;' | tee /dev/null id | name ----+------ (0 rows)
Expected Behaviour
I would expect that deleting a user would delete all access rights that user had.
So, I would expect that deleting a user would delete all OAuth apps in their name and immediately revoke all tokens that were given out to it. The tokens not being revoked means a user can leave a ghost app around, at least
Right now you apparently can't get a new OAuth token issued (:+1:), but previously issued ones are still valid (:-1:), meaning someone who phished you into opening their malicious app can hide their tracks.
The HTTP 500 should instead be the standard HTTP 400 with "Client ID not registered":
and clicking "Sync" on Drone (or any similar app) should fail.