Our latest exploration has uncovered critical vulnerabilities within Microsoft 365, highlighting significant security risks that could compromise sensitive business data. These vulnerabilities expose a vast array of records—ranging into the tens or even hundreds of millions—across key sectors such as finance, healthcare, and government. This post dives into the details of these vulnerabilities, providing a closer look at how they were discovered and the potential consequences for businesses worldwide.
Today, we will discuss three critical vulnerabilities discovered in the Dynamics 365 and Power Apps Web API. Dynamics 365 is Microsoft's CRM/ERP solution, and Power Apps are low/no-code platforms for building applications and websites used by businesses worldwide.
Before diving into the details, let's set the context. When communicating with a Power Pages application, data is stored in the "Dataverse" and can be optionally exposed via an API with fine-grained access controls. All of the vulnerabilities identified expose every other column in a table as long as a single column is exposed, which is a very common configuration.
I was doing some web application penetration testing on an app hosted on Microsoft Power Pages, and on a whim, my pentester spidey senses told me to play with the API a little extra which is where we discovered the vulnerabilities.
Vulnerability Overview
Vulnerability 1: Lack of Access Control on OData Web API Filter
To set the scene for how a request to the API normally looks, we have the default contacts table with only the fullname field exposed. It can be queried like this:
This is working as intended, but most tables in power apps hold sensitive info, especially the contacts table. Fine-grained access controls can be used to prevent users from accessing more than intended so this data stays secure. For example, this is the result of a request attempting to pull password hashes from the contacts table:
As you can see, the API correctly denies access to this column. Everyone knows leaking password hashes would be very bad! In this case, the first vulnerability is a lack of access control on the OData Web API filter. The Power Pages API supports these filters, which completely ignore the access controls. This can be seen in the below screenshot where we get a subset of results, only including any that have a password hash starting with the string 'ABq':
On the other hand, if I give a query that has no hashes matching the filter it will return an empty array:
Although we can't see the adx_identity_passwordhash column, we can still interact with it. The million-dollar question is, how can this be weaponized?
If you are familiar with SQL Injection (SQLi) you will recognize this technique. We can perform a blind boolean-based search to extract the complete hash. This process involves guessing each character of the hash sequentially until we find the correct one. For example, we start by sending startswith(adx_identity_passwordhash, 'a') then startswith(adx_identity_passwordhash , 'aa') then startswith(adx_identity_passwordhash , 'ab') and so on. until it returns results that start with ab. We continue this process until the query returns results that start with 'ab'. Eventually, when no further characters return a valid result, we know we have obtained the complete value.
Vulnerability 2: Exploiting the Orderby Query
Microsoft patched the initial vulnerability on February 4th 2024, causing the filter technique to return the same response as the select statement when referencing a disabled column, as shown below:
While validating this patch, I discovered another vulnerability that also allows access to the disabled columns. However, this time it's even worse because it directly returns the data, making large-scale exploitation much easier!
The root cause of this second vulnerability lies in the orderby query of the same API. My initial approach was to get tricky and exploit the orderby to infer the characters or at least a range of characters based on the surrounding data and other fields, thankfully I didn't need to go that deep and as you can see in the screenshot below, it will helpfully just return the disabled column (emailaddress1) for me:
The only caveat here, similar to the previous vulnerability, is that you need a single column open to perform the orderby query. Additionally, it must be orderby desc. If you use the default orderby (ascending), it will still sort the data when it shouldn't, but it will not display the data.
Vulnerability 3: Exploiting the FetchXML API
Just when we thought the vulnerabilities were patched, I discovered yet another critical flaw - this time in the FetchXML API. This third vulnerability can be exploited just like the previous orderby vulnerability, allowing attackers to access restricted columns using an orderby query.
The FetchXML API vulnerability is particularly alarming due to its versatility. When utilizing the FetchXML API, an attacker can craft an orderby query on any column, completely bypassing the existing access controls. Unlike the previous vulnerabilities, this method does not necessitate the orderby to be in descending order, adding a layer of flexibility to the attack.
Just like the previous vulnerabilities, a single exposed column is sufficient to exploit this vulnerability and gain unauthorized access to sensitive data.
Bypassing the access controls is all well and good, but what's the impact? Who's affected? Is the world ending? Let's find out!
Impact Analysis
We now understand that any data in the table can be accessed as long as a single column is exposed to the internet. For our example, we are going to only analyze Power Pages but keep in mind this is likely to be an issue in other Power Platform products which use the same API. The first thing we need to know is who is using Power Pages.
Who's at risk?
Enumeration of other tenants is against the Microsoft's rules of engagement, so we need a little conjecture here. In reality, an attacker would use a subdomain enumeration tool (like subfinder) to find applications running on powerappsportal.com and then a quick look (or script) over the APIs in use to find any tables with an open column.
Considering the popularity, it's safe to assume there were thousands, if not tens of thousands of power pages applications vulnerable. The most common entities are likely large consulting firms which tend to favour this kind of application and nonprofits since Microsoft offers them significant discounts, although it would extend to anyone including health care and financial institutions.
The default tables most commonly used tend to be the accounts and contacts tables. Both of them contain names, phone numbers, addresses, email addresses and plenty of other personal information. The accounts table specifically has a bunch of financial information and the contacts table holds government IDs, password hashes and more!
While the exposure of this data is undoubtedly serious, we must consider how much of it holds meaningful data. To maintain the integrity of company data we can't access it to verify directly, but it's well known that Microsoft alone has millions of users on their Microsoft forums running on Power Pages.
We have no way to tell if all this data has been accessed or leaked anywhere yet but let's play out the scenario that it is, since it's only a matter of time before vulnerabilities like this are exploited.
Note: Microsoft confirmed that they did an analysis of these vulnerabilities and alerted affected parties as appropriate.
Breach Impact
The exposure of all this information is serious business, and it has been sitting here available for any half-decent hacker to stumble across. The implications of a malicious actor compromising this data are significant, so let's explore some potential scenarios.
The first scenario involves a malicious actor compiling a large list of password hashes and emails. Since most of these emails are likely to be corporate, they could also serve as credentials for corporate accounts. In our experience, a skilled hacker can typically compromise a business using any internal user as a foothold, let alone admin accounts that these applications likely store. Passwords can often be cracked; during penetration tests, we see anywhere from 15-50% of passwords cracked, although this can vary widely depending on the business. Considering this, we can assume that thousands of businesses could be directly and completely breached due to this single vulnerability.
A more likely scenario, due to the lower risk and effort required for threat actors, would be selling the data. This approach would still result in the same breaches but on a larger scale and with less targeted attacks. If we consider the broader impact of the leaked data, it resembles breaches we have seen from companies like Optus and Latitude Finance. These breaches affected approximately 10-15 million people to varying degrees. Although this situation could be worse due to the credentials being leaked, our focus in the next section is on the sheer number of records exposed.
Financial Impact
Although it is likely larger, we can use the Latitude data breach as a benchmark and assume 14 million records were exposed.
According to the IBM Cost of a Data Breach report, the average cost per record leaked is $165 which would put the (very) approximate cost of exploitation here at $2,310,000,000 (2.31 billion USD) for the affected businesses.
Disclosure
Upon completing our initial analysis, we aimed to disclose the information immediately to prevent malicious actors from finding and exploiting these vulnerabilities. We provided a detailed writeup of the first vulnerability and its associated risks on December 2nd, 2023. This included a GIF demonstrating the exploit to extract password hashes and a Proof of Concept (PoC) for testing.
Over the next month and a half, there was significant back and forth, including a few misunderstandings. However, we received an update confirming that the vulnerability had been patched on February 3rd, 2024. Unfortunately, someone else had reported it before me, so I promptly confirmed the remediation... but as you know, that wasn't the end.
While validating the remediation, we discovered the second vulnerability. As described above, it has a similar impact but it's even easier to exploit at scale. This second vulnerability was reported on February 13 and confirmed on the 22nd, it was also eligible for a bounty this time! Since it has such a wide reach, it was eligible for the $20,000 cross-tenant information disclosure award. The vulnerability was fixed at the start of March.
A few weeks later on the 22nd I went in to have a quick look around for any more vulnerabilities and found the third one, which I reported immediately. The bounty for this one was smaller despite the same impact but it has been patched as of the 15th of May. I might go back and look for some more, but only time will tell!
Conclusion
The discovery of vulnerabilities in the Dynamics 365 and Power Apps API underscores a critical reminder: cybersecurity requires constant vigilance, especially for large companies that hold so much data like Microsoft. These flaws highlight the risks that come with digital innovation, exposing potential financial and reputational damages that can run deep for businesses worldwide.
Finding these vulnerabilities three times suggests a systemic issue within the platforms security architecture. This recurring problem indicates that more vulnerabilities likely exist in the platform, posing an ongoing risk. Microsoft needs to have a deep look at the design of this platform and the security processes involved in its development, it is something we do regularly and would be much more effective than external people poking around blindly.
This is a wake-up call for organizations to bolster their defences, undergo regular security audits, and cultivate a culture of cybersecurity awareness. If you need assistance with cybersecurity or have any questions, feel free to get in touch. We are here to help.