Bitbucket is one of the worlds leading version control software allowing millions of developers to manage Git repositories and collaborate on source code. Bitbucket is developed by the Australian software company Atlassian which is also kown for Confluence and Jira. In this blog post we will analyse how a common but often overseen security issue leads to a critical vulnerability in Bitbucket (CVE-2019-3397). The issue is caused by the insecure extraction of a compressed TAR archive.
Impact
In Bitbucket the four different user roles Bitbucket User, Project Creator, Admin and System Admin exist. An attacker with the permissions of the role Admin can abuse Bitbucket’s Data Center Migration tool to drop an executable shell script in an arbitrary directory. This is caused by a directory traversal within a TAR archive. In order to gain remote code execution, the attacker can drop a Git hook which is executed if a special event occurs in the repository e.g. a pull or push request. The vulnerable Data Center Migration tool was introduced in version 5.14 of Bitbucket Server and can be exploited with a Bitbucket Data Center license.
Bitbucket’s Migration Endpoint
The Data Center Migration tool allows Admins or System Admins to migrate Git repositories from Bitbucket Server to Bitbucket Data Center. To start the migration process the admin has to export the repositories from the Bitbucket Server instance first. During the export process a TAR archive with the following structure is being created.
Example TAR archive
As we can see, the exported TAR archive contains multiple GZIP and TAR compressed files. Especially the file hooks.atl.tar.atl.gz
(line 9) looks suspicious since it contains Git hooks which are scripts that are executed every time a particular event occurs in a Git repository. Manipulating such a TAR archive entry with the ../../
notation and starting the import process leads to a Remote Code Execution vulnerability as described in the next section.
Insecure Archive extraction
During the import process of a repository, the Git hooks from the file hooks.atl.tar.atl.gz
are stored in the directory ${BITBUCKET_DATA}/shared/data/repositories/${REPO_ID}/imported-hooks/
and are therefore ignored from being executed since the regular hooks of a repository are stored in the directory ${BITBUCKET_DATA}/shared/data/repositories/${REPO_ID}/hooks/
. However, if an attacker controls the contents of the file hooks.atl.tar.atl.gz
it is possible to traverse out of the intended directory and drop a hook in an arbitrary directory. This is caused by insecure extraction of the GZip compressed TAR file.
The following code snippet shows the simplified function extractToDisk()
which takes the path to the file hooks.atl.tar.atl.gz
as parameter target. Then the function read()
is called with the lambda expression in line 4-9. This lambda expression implements the function accept()
of the interface IoConsumer<T>
.
Insecure Extraction of Archives
The following code snippet shows the function declaration of the function read()
. This function iterates over all archive entries and calls the function accept()
on an object of the class TarEntrySource
containing the user input. We can see that the unsanitized user input from the source org.apache.commons.compress.archivers.tar.TarArchiveEntry.getName()
(line 7) reaches the sensitive sink java.nio.Paths.get()
(line 9) indicating a Path Traversal vulnerability.
Since the function accept()
is implemented by the above defined lambda expression, we can track the user input to the to the function call of TarEntrySource.extractToDisk()
(line 7).
Reading the TAR archive
The following Listing shows the function extractToDisk()
of the class TarEntrySource
which takes the unsanitized path as function parameter. We can see that all sub directories of the path are created (line 5) and the file is copied into that directory (line 8).
Dropping the File
This path traversal vulnerability enables an attacker to drop a Git hook in an attacker controlled BitBucket repository. However, if the file permissisons of the shell script are not set properly e.g. the execute bit is not set the Git hook is not being executed. Interesting to mention is that a TAR archive contains meta information of a file entry like the modification date, the user name, the group name and the file mode (file permissions). In line 11, the file permissions are set to the corresponding permissions of the archive entry.
Timeline
Date | What |
2019/02/27 | Reported the Path Traversal vulnerability to Atlassian. |
2019/03/11 | Atlassian confirmed the vulnerability and assigned issue BSERV-11706. |
2019/04/01 | Atlassian fixed the issue in Bitbucket 6.1.2. |
2019/05/22 | Atlassian published a security advisory for Bitbucket. |
Summary
In this post we have analysed how the insecure server-side extraction of a TAR archive leads to a critical vulnerability in Bitbucket. Bitbucket is used by millions of developers world-wide which introduces a special interest for attackers. There are different attack scenarios to exploit this issue. ABitbucket Usercould lure a user of the roleAdmin (notSystem Admin) to import a malicious TAR archive in order to gain control of the remote Bitbucket server or a maliciousAdmincan exploit this issue by himself. It is highly recommended to update Bitbucket Data Center to the most recent version. We would like to thank the Atlassian team for the professional collaboration on fixing this issue.