CVE-2020-5497 - MITREid Connect Cross-site Scripting

MITREid Connect Cross-site Scripting Vulnerability: CVE-2020-5497 Here's the situation: I was performing a penetration test that integrated with MITREid Connect for authorization.

Aaron Bishop
Cybersecurity
Penetration Testing
Security Research
CVE-2020-5497 - MITREid Connect Cross-site Scripting

'Alert' - Here be cross-site scripting

Here's the situation: I was performing a penetration test that integrated with MITREid Connect for authorization. I transitioned from the Customers Web Application to the MITREid Connect web interface and was greeted by:

OpenID Connect JavaScript alert example

If you've been through some sort of web application security assessment the above image may look familiar, a JavaScript alert. It is commonly used by penetration testers to identify potential Cross-site Scripting because it is easy, visible, and demonstrates that the analyst was able to get the Application to execute arbitrary JavaScript.

I modified my username to be Test</script><script>alert(2)</script>. If my username was included in a <script> element, my username would close that <script> element and a new <script> element that triggers an alert would be created.

It just so happens, my username was included in the page, unsanitized, in a <script> element that performed several function calls including getUserInfo:

// get the info of the current user, if available (null otherwise)
function getUserInfo() {
    return {"sub":"1234567890","name":"
Test</script><script>alert(2)</script>","preferred_username":"Test","given_name":"Test</script><script>alert(2)</script>","family_name":"test","email":"test@test.com","email_verified":true};
}

My username was also included later in the page, outside a <script> element:

<li><a href="manage/#user/profile">Test</script><script>alert(2)</script> Test</a></li>
<li class="divider"></li>
<li><a href="" class="logoutLink"><i class="icon-remove"></i> Log out</a></li>

The username appears outside a <script> element so a closing </script> is unnecessary and will essentially be ignored by the browser; my username created a new <script> element which I controlled.

I noticed the Cross-site Scripting occurs before several js files are referenced:

193<li><a href="manage/#user/profile">Test</script><script>alert(2)</script> Test</a></li>
194<li class="divider"></li>
195<li><a href="" class="logoutLink"><i class="icon-remove"></i> Log out</a></li>
...
322<script type="text/javascript" src="resources/js/client.js" ></script>
323
324<script type="text/javascript" src="resources/js/grant.js" ></script>
325
326<script type="text/javascript" src="resources/js/scope.js" ></script>
327
328<script type="text/javascript" src="resources/js/whitelist.js" ></script>
329
330<script type="text/javascript" src="resources/js/dynreg.js" ></script>
331
332<script type="text/javascript" src="resources/js/rsreg.js" ></script>
333
334<script type="text/javascript" src="resources/js/token.js" ></script>
335
336<script type="text/javascript" src="resources/js/blacklist.js" ></script>
337
338<script type="text/javascript" src="resources/js/profile.js" ></script>
339
340<script type="text/javascript" src="resources/js/admin.js"></script>

Some files, like admin.js, perform a check to see if the isAdmin function returns true before granting access to restricted pages:

root: function() {
if (isAdmin()) {
 this.navigate('admin/clients', {
 trigger: true
 });

 } else {
 this.navigate('user/approved', {
 trigger: true
 });
 }
}

I exploited the Cross-site Scripting to force isAdmin to return true and grant other roles to my user:

example of exploited Cross-site Scripting

Previously restricted pages were accessible, however, no sensitive information was disclosed and I was unable to modify the application after bypassing the client-side isAdmin check.

MITREid Connect is an open-source project available on github so I cloned the project and set about tracking down the cause. The search led to two places where information a user can alter is included in the page, the first being in header.tag:

// get the info of the current user, if available (null otherwise)
function getUserInfo() {
 return
${userInfoJson};
}

The second in topbar.tag:

<li><a href="manage/#user/profile">${ longName }</a></li>
<li class="divider"></li>
<li><a href="" class="logoutLink"><i class="icon-remove"></i> <spring:message code="topbar.logout"/></a></li>

I reported the issue which has subsequently been assigned CVE-2020-5497.

Join Thousands of Security Professionals.

Subscribe Now

Get the Guide To PCI Compliance

Download

Get a Quote for Data Security

Request a Quote