Who stole my cookies? XSS vulnerability in Microsoft Azure Functions
Cloud-based services are a growing asset for enterprises to optimize scale and reduce deployment efforts.
In our research, we found a web XSS vulnerability on Microsoft Azure Functions due to an improper implementation of access control and poor enforcement of SOP.
This paper shares a behind-the-scenes window into our process of discovering the vulnerability and developing a proof of concept that demonstrated its exploitability. Following our report, the vulnerability was patched by Microsoft in Q1 of 2022.
Browser Security Concepts
The browser is responsible for client-side security measures aimed at limiting the web attack surface as much as possible. One of these is sandboxing, a mechanism aimed at isolating each accessed website on the client-side, so that accessing a malicious origin will have no effect on other concurrently connected origins or the data they store, such as cookies, databases or other files.
Another basic client-side security measure is SOP (Same Origin Policy). SOP is a basic browser-enforced standard that prevents origins from sending information directly from one domain to another when the HTTP request is unique. Essentially, it prevents sharing of data across domains.
A unique HTTP request requires the right CORS permission. Here are some examples of unique HTTP requests:
- Unique content-type XML – application/xml
- Unique content-type JSON – application/JSON
- Unique HTTP method – PUT, DELETE, PATCH
If the HTTP request is unique, the browser will send preflight (OPTIONS) requests to inspect the CORS policy and ascertain if the request can be permitted.
CORS (Cross-Origin Resource Sharing)
SOP aims to prevent direct unique HTTP requests to other domains, and as part of the preflight flow an OPTIONS request is sent in advance.
The CORS policy is passed via an HTTP header, which indicates to the browser what the policy is for accepting “unique” HTTP requests.
Let’s consider an example. Imagine a company “Bank” that has 2 websites:
- “bank.com” which contains all static files for the website (HTML, CSS, JS, PNG, and more).
- “api-bank.com” which implements all the dynamic logic of the website and is responsible for all banking actions performed from the website. This website accepts JSON content-type.
From the browser’s perspective, the client accesses “bank.com” and then “bank.com” tries to access “api-bank.com” to get dynamic information for the specific client.
The following flow will be forced:
SOP (Same origin policy) example
If the CORS policy on api-bank.com were to block bank.com from communicating with it (Step 3), the requests from bank.com would then be blocked by the browser and wouldn’t be sent to api-bank.com.
XSS (Cross-Site Scripting)
XSS is a category of code injection aimed at injecting malicious scripts into otherwise trusted websites.
There are 3 main types of XSS:
- Reflected – The malicious JS code is triggered by the specific client by leveraging an input which is reflected to the client
- Persistent – The malicious JS code is permanently injected into the website data (DB, static files, logs, etc.) and is presented to users by the server
- DOM – The malicious JS code is executed in the context of a legitimate client-side code section belonging to the website
Our investigation focused on reflected XSS, where the malicious code gets sent back by the server to the client following a malicious HTTP request which contains it.
Below is an example of the flow we are interested in:
Azure Functions provides an auto-scaling cloud service available on-demand for developing websites that can run code sections without having to worry about resources, updates, and operational maintenance.
Our findings concern one of the domains used by Azure to serve their Functions platform services: functions.azure.com.
Discovery of the Vulnerability
After setting-up a function app resource, we intercepted the traffic originating from the browser to the Azure portal, and we noticed the following request had been sent to “functions.azure.com”:
A parameter called “url” piqued our interest. The request indicated that “functions.azure.com” was sending a request to the website in the “url” along with the headers and body configured in the parameters.
Since the content-type of the response is “text/html”, this means that the browser will try to parse the response as HTML, a well-known launchpad for XSS attacks.
With this information at hand, we created a simple HTML web page containing an embedded script:
The screenshot below shows what happened next: After we passed the address of our malicious HTML to the url parameter, we noticed that the script was contained in the response, unsanitized and unencoded, and under the functions.azure.com context. and that the host header value was “functions.azure.com”.
At this point, all we needed was to create a simple HTML form to send this request automatically and exploit the XSS in “functions.azure.com”.
This may seem trivial and straight-forward, however, the content type of the request is application/json. Owing to the SOP mechanism, we cannot send “unique” HTTP requests directly to a website that is not part of the same domain.
Additionally, we needed to send the request over an HTML form for the redirection to be followed automatically. Again, sending application/json content type cannot be done via HTML forms.
To execute the attack, we depended on the server supporting x-www-form-urlencoded content type for the following 2 purposes:
- Bypassing SOP (text/html) with non-unique HTTP requests to avoid preflight.
- Ability to execute our requests using an HTML form, which does not support application/json
In our next attempt, we tampered with the format of the body of the request to fit x-www-form-urlencoded content, hoping that the remote server (“functions.azure.com”) would accept it; and against all odds, it did!
For our POC, we set up a website, which automatically executed this request, thereby proving that we had achieved full-fledged XSS on “functions.azure.com”.
Up to this point, we have seen how we, as researchers, can tackle the discovery of this vulnerability. However, the attacker point of view is somewhat different, as presented in the following diagram:
Of course, the malicious HTML can contain any content to leverage phishing techniques. The page will be displayed in the context of functions.azure.com. We could even produce a very legitimate looking login form for phishing purposes, as in the following screenshot. As a phishing site, this would likely prove highly effective and quite damaging.
After demonstrating how we uncovered an XSS vulnerability in Microsoft Azure Functions including key security concepts and the attack chain, you should now be able to leverage attacks and protect assets in a better way.
For any questions, feel free to reach out at email@example.com or read more research from Pentera Labs.
Watch the webinar on-demand here.
The version of an MSSQL database is a valuable piece of information for cyber attackers. With the version details in hand, they can attempt to find and exploit any of the version’s known vulnerabilities. As part of our research at Pentera Labs, we attempted to obtain the version of the widely-used MSSQL (Microsoft SQL Server)...
Digitalization initiatives are connecting once-isolated Operational Technology (OT) environments with their Information Technology (IT) counterparts. This digital transformation of the factory floor has accelerated the connection of machinery to digital systems and data. Computer systems for managing and monitoring digital systems and data have been added to the hardware and software used for managing and...
Despite major investments in their security suites, organizations continue to be breached. Our Co-founder and CTO, Arik Liberzon, recently sat down with CyberNews to discuss the value of the adversarial perspective and where his inspiration from Pentera came from. Starting out, I arrived at the idea for Pentera and Automated Security Validation in a pretty...