“Cross-site scripting (XSS) is perhaps the most well-known web vulnerability that can get your site hacked. XSS occurs when a web page displays user input — typically via JavaScript — that isn’t properly validated. A criminal hacker can take advantage of the absence of input filtering and cause a web page to execute malicious code on any user’s computer that views the page.”
The ideal remediation for such client-side injection attacks is to perform output encoding, but some developers prefer fixing the issue by using a regex that filters certain keywords and/or special characters popularly used as part of an XSS payload. This definitely does work in cases where the developer understands the vulnerability and uses the right blacklist regex patterns, but as you may be aware, there are non-exhaustive alternatives to functions and methods in JavaScript which can be used to trigger a client-side injection attack. This blog aims to emphasize that just relying on blacklisting or filtering as part of server-side validation is not the best security practice as there are, and will always be ways of bypassing such implementations. Researchers are always going to find new/alternate ways to bypass existing protocols.
The Oracle cloud-based utility allows users to build and deploy enterprise applications, and after spending a couple of hours on its major functionalities, I could see that user input sent in every form submission request was properly encoded before it was rendered in the response. But this was oddly not the case for “every” functionality; the application was treating user input differently for a (very) few functionalities (legacy functionalities, maybe?). To elaborate, it looked like the application (in these few functionalities) was designed to filter out certain special characters and keywords in the response due to which normal XSS payloads would not work as-is.
I spent the next couple of hours understanding the regex pattern behind which the filtering mechanism was implemented and crafted the perfect payload that bypassed the filter. The result was an ‘alert box’ on the screen, which was rendered every time the functionality was accessed, i.e, Stored Cross-Site Scripting.
I made a list of all the modules that were using the above implementation and observed that they were all vulnerable to Stored Cross-Site Scripting, and one such module allowed a user to create and share forms with other users who are part of a certain group (DEV, QA, UAT, PROD, etc.), i.e., Once a form is filled and submitted by a user, the contents of the form is visible to all the users of the group upon login (including the user who submitted the form).
I triggered the newly crafted JavaScript XSS payload as part of the form submission and observed that the JavaScript payload was loaded the moment any valid user of the group (even administrators) logged into the application. Next, I modified the XSS payload to make the application parse document.write(‘aaaa’) when the user logs in to the application.
i.e., Instead of seeing a fancy ‘alert box’ on the screen, logged-in users of the group would be directed to a blank page with ‘aaaa’ in the response.
You might wonder the following —
Ans 1. The application sends a dynamically generated unique identifier in every request, i.e, for every button clicked, the application sends a randomly generated identifier, which is validated and mapped in the server due to which it would not be possible for users to access any other functionality unless they could predict the identifier value. An example of the request identifier below.
:640991690762043326726::
Ans 2. Now that the user has no way of accessing any other functionality in the application (See Ans 1) and that the XSS payload is executed every time any valid workspace user logs in, no user (not even the administrator) can access any functionality in the application. The Oracle team had to clear the payload in the backend database for the application to be accessible again.
During the initial disclosure, the Oracle team ruled the vulnerabilities as intended functionalities, but after several back and forths, the issues were accepted and fixed in their October 2020 and Jan 2021 patch release cycles.
It was great collaborating with the Oracle security team, and I am delighted to have my first set of published CVEs from Oracle. More to come!
CVE-2020–14762 | CVE-2020–14763 | CVE-2020–14898 | CVE-2020–14899 |CVE-2020–14900 | CVE-2021–2116 | CVE-2021–2117