Details
-
Bug
-
Status: Closed
-
Medium
-
Resolution: Fixed
-
None
-
None
-
XRAYCLOUD 2024 Sprint 8, XRAYCLOUD 2024 Sprint 9
-
Description
Summary
It has been identified that attackers, without needing to authenticate, can upload arbitrary files to a Jira instance via the XRAY plugin.
Description
As a proof of concept, the following image shows the error message displayed by XRAY when accessing one of the plugin's reports without authentication, highlighting the contextJwt generated for the anonymous user:
![screenshot-086_9.png](https://bugcrowd.com/xpandit/submissions/31579d76-ca6d-430e-b7e9-e4abc98e49d9/attachments/7970480b-9a8e-4223-9e39-284572573da8 "screenshot-086_9.png")
Subsequently, as demonstrated in the next image, it was possible to upload an arbitrary file to the Jira instance by providing an ID of any issue (in this case 10000, the first issue of Jira), and an invalid object-id (note the 1337 at the beginning of the object-id), using the attacker's session token:
![screenshot-086_9.5.png](https://bugcrowd.com/xpandit/submissions/31579d76-ca6d-430e-b7e9-e4abc98e49d9/attachments/5b67b5dd-c489-4e81-b760-4c55c407f22a "screenshot-086_9.5.png")
Finally, to verify that the file was indeed stored in Jira, using the administrator's API token, I submitted the following request to download the file in question:
![screenshot-086_10.png](https://bugcrowd.com/xpandit/submissions/31579d76-ca6d-430e-b7e9-e4abc98e49d9/attachments/202683ad-21aa-4eb0-84d9-92e2abd91e64 "screenshot-086_10.png")
Impact
External attackers can upload malicious files to Jira instances through this vulnerability, thus spreading malware/ransomware aimed at compromising user access or their machines.
Steps to Reproduce
1. Log in as an administrator and install the "XRay" plugin on Jira Cloud.
2. Navigate to {}Apps -> Manage Apps -> XRAY -> Test Environments{}.
3. Create a new Environment and save.
4. Create a new project.
5. Access the created project and go to {}Project Settings -> Permissions{}.
6. Click to edit the permissions.
7. Update the {}Browse Project{} permission and add the {}Public{} group.
8. Save the permission.
—
1. Access the created project's URL in incognito mode.
2. Start Burp suite.
3. Replace the URL path to `/plugins/servlet/ac/com.xpandit.plugins.xray/xray-testexecs-report` (`https://JIRA-HOSTNAME.atlassian.net/plugins/servlet/ac/com.xpandit.plugins.xray/xray-testexecs-report`).
4. In Burp suite, filter for `xray.cloud.getxray.app` and copy the JWT in the {}X-acpt{} header present in the server's response.
5. Submit the following request after replacing {}
{} with the obtained JWT.
```
POST /api/internal/attachments?testIssueId=10000&testVersionId=133707b39de4e8d5262964da HTTP/1.1
Host: xray.cloud.getxray.app
Access-Control-Allow-Origin: *
Content-Type: multipart/form-data; boundary=---------------------------6970649553716101808512788092
Content-Length: 259
X-Acpt: {jwt}
-----------------------------6970649553716101808512788092
Content-Disposition: form-data; name="attachment"; filename="malware.exe"
Content-Type: application/json
Malware uploaded by attacker
--------------------------{}{}6970649553716101808512788092{}{-}
```
1. Observe that the application returns a success message after uploading the file in question.
—
1. If preferred, copy the UUID of the returned file. Authenticated as an administrator, go to {}Apps -> Manage Apps > XRAY -> API Keys{}.
2. Generate credentials for the administrator user.
3. Submit the following request after providing API credentials in the client_id and client_secret parameters to obtain a JWT for accessing the API.
```
POST /api/v1/authenticate HTTP/1.1
Host: xray.cloud.getxray.app
Accept-Encoding: gzip, deflate, br
Accept: /
Accept-Language: en-US;q=0.9,en;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.6261.112 Safari/537.36
Connection: close
Cache-Control: max-age=0
Content-Type: application/json
Content-Length: 135
```
1. Copy the JWT returned by the server
2. Submit the following request after replacing {}
{} with the obtained JWT and {}
{file-uuid}{} with the UUID of the file uploaded by the attacker.
```
GET /api/v1/attachments/{file-uuid} HTTP/1.1
Host: xray.cloud.getxray.app
Authorization: Bearer {jwt}
```
1. Note that the server returns the file uploaded by the attacker.