Skip to content

User not authorized to view a repo in HTTP but can still clone/fetch it in SSH #17364

Closed
@hyjwei

Description

@hyjwei

Gitea Version

1.15.4

Git Version

2.33.1

Operating System

Linux amd64

How are you running Gitea?

Gitea static prebuild binary (https://dl.gitea.io/gitea/1.15.4/gitea-1.15.4-linux-amd64)

Database

SQLite

Can you reproduce the bug on the Gitea demo site?

No

Log Gist

No response

Description

I apologize for the poor writing and text format because I rarely submit an issue in github, although I do want to help to make improvement. Please correct me if I was wrong.

I suppose that if a Gitea user cannot view a repo in the web interface (getting code 404 with error "you are not authorized to view it"), he shouldn't be able to read/clone/fetch the same repo through ssh.

However, the current behavior of Gitea seems to permit the user to read the repo (if he knows the name) in SSH, even for restricted users, as long as the repo is not private. And I believe this should be fixed to have a consistent behavior in both cases.

  • Example 1: A user sets "User Visibility" to private, but doesn't set his repo to private. Other users cannot view his repo in web, however, they can still clone/fetch his repo in ssh.
  • Example 2: Organization visibility is private, but the repo under the organization is not private. Same as above, no access in web, but able to clone/fetch in ssh.
  • Example 3: Restricted user cannot view other repos (unless added to the collaborators of the repo) in web, but still able to clone/fetch in ssh.

Gitea will return "Unauthorized" error upon push and log error "[E] ssh: User: XXXX with Key: XXXX is not authorized to write to XXXX/XXXX.:"

I am not familiar with Go but I guess the code in routers/private/serv.go:282 has something on it:

        // Permissions checking:
        if repoExist && (mode > models.AccessModeRead || repo.IsPrivate || setting.Service.RequireSignInView) {
...
                        userMode := perm.UnitAccessMode(unitType)

                        if userMode < mode {
                                log.Error("Failed authentication attempt for %s with key %s (not authorized to %s %s/%s) from %s", user.Name, key.Name, modeString, ownerName, repoName, ctx.RemoteAd
dr())
...

The logic here is that if a repo exists, when mode is higher than read, or repo is private or site requires signin to view, then it will check if user has proper permission. Therefore, if a repo is not private and mode is read, there will be no user permission check, although the user's permission could be none (and shouldn't be able to read the repo).

I suggest to enable user permission check for read mode as well. So the condition should be changed to something like "mode >= models.AccessModeRead".

I am sorry that I don't have Go env to compile and test the code myself.

Screenshots

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions