Microsoft’s Power Platform services offer a low-code/no-code (LCNC) platform that includes data analytics (Power BI), website development (Power Pages), virtual assistants (Power Virtual Agent) and a sort of “full application” development (Power Apps). These platforms can give less technical business users the ability to create solutions that would traditionally require a more technical developer with programming experience.
While LCNC platforms can be a powerful tool for business users, the developers of the platform must take care that security is baked in at every step. Business users without formal programming experience may not have the same level of security awareness as a modern software developer. This can increase the likelihood of user misconfigurations being introduced into these LCNC platforms.
In this blog post, we’re going to look at how, in 2022, X-Force Red’s Adversary Simulation team combined an at-the-time common user misconfiguration with a still-present security bypass issue in Microsoft’s Power Apps platform. This enabled X-Force Red to breach a hardened external perimeter and gain code execution to an on-premises SQL server, which ultimately resulted in full Active Directory compromise.
In 2022, the default Power Apps behavior meant that when a Power Apps application was shared with users, any associated connections would be shared as well. This made it very easy for users to accidentally share connections with all users in an organization, when they may have only meant to share the frontend application. This behavior was changed in January 2024, according to Microsoft, making it much less likely that users will accidentally share out connections.
In 2022, however, X-Force Red identified a SQL connection using an “On-Premises Data Gateway” to connect to an on-prem SQL server that had been widely shared in this manner. While native SQL queries are not supported for on-prem SQL servers in Power Apps flows, X-Force Red identified that the “Transform data using Power Query” action could be used to execute native SQL queries against on-prem servers. This allowed X-Force Red to pivot to the on-prem SQL server and ultimately achieve all objectives for the engagement.
This bug was recently reported to the Microsoft Security Response Center (MSRC), and they have assigned it a Low severity, so we are now publishing the details.
Power Apps allows users to create “apps” and “flows” using a drop-and-drag GUI that’s typical for LCNC platforms. Apps can be used to create front-end applications which are generally used to pull data from somewhere and display it to the user. Below is a “Budget Tracker” demo application provided by Microsoft which takes in data from an Excel spreadsheet and displays it to the user.
The other side of Power Apps, Flows, will be familiar to anyone who has used another LCNC service like Azure Logic Apps before. Flows allow users to create a flowchart-like program and are typically used to pull data in, process it and then send it somewhere. Below is a very basic flow that makes an HTTP request and then parses the resulting JSON.
Power Apps has a suite of “Connectors” that allow users to perform tasks like ingesting data or sending emails, without resorting to using a bunch of HTTP request actions. Many of these connectors are just prebuilt libraries of HTTP requests, but they abstract away all of the technical details from the user. Instead of having to construct an HTTP request to the Graph API to get information about an Entra ID user, you can simply hook up an Entra ID connector and use the “Get User” action.
Power Apps offers connectors for many popular services, including both Microsoft services and 3rd party offerings. You can grab files from SharePoint, convert a document to PDF using Adobe PDF Services or restart Virtual Machines in Azure, just to name a few. When you create a connection, you’ll be prompted to provide authentication material depending on which service you’re connecting to. For pretty much everything related to Microsoft, you’ll simply authenticate using your O365 account.
Note: For the rest of this post, I’m going to use “connector” to describe the library of actions in Power Apps (ex: the Entra ID connector), and “connection” to refer to a connector that has been created and authenticated by a user (ex: the Entra ID connection authenticated as john.smith@contoso.com) and can be used to create new actions.
For as long as this connection exists, your authentication will be associated with it. Any user with access to that connection can create new actions that will use your authentication. For example, if you create an Entra ID connection, then another user with access to that connection could create an “Add user to group” action, which will use your authentication, even if that user would not have the necessary Entra ID permissions to add a user to a group. I’ve previously blogged about abusing this in Azure Logic Apps, and found a serviceable privilege escalation exploit in Azure Logic Apps that abused this functionality.
Up until 2024, this type of attack was far more likely to occur in Power Apps. It used to be the case that when you would share an application that uses a connection, the associated connection would also be shared. You can see this documented on this page from Microsoft, which hasn’t been updated since 2022. However, according to this page from 2024, this is no longer the case. Now, you’ll need the connection to be shared with your account, which is a far less likely misconfiguration. This could have been the result of the BlackHat 2023 talk “All You Need Is Guest” by Michael Bargury, an excellent talk which also covered enumerating and dumping information from Power Apps.
What if you need to access data that isn’t available on the internet? What if you needed to access data from an on-premises SQL server? Microsoft has already thought of this and created on-premises data gateways. Gateways are installed on an on-premises host and essentially act as a proxy that allows Power Apps connectors to talk to on-premises resources. To access an on-premises SQL server, you can simply install a gateway on the SQL Server (or on another server, or maybe even on your workstation if you’re doing shadow IT) and then use the SQL connector to perform queries against the server.
There are six supported authentication types for connecting to a SQL server, although not all of them will work for on-premises SQL servers. For on-premises, you’ll likely be using either SQL Server authentication or Windows authentication, providing either your AD credentials or local SQL credentials.
Once you’ve created your connection or gained access to a shared one, you can perform a host of actions against the SQL Server. The one that will catch most readers’ eyes is “Execute a SQL Query (V2)”.
If you’re not familiar with the implications of being able to execute native SQL queries, then I suggest you read this blog from my teammate, Sanjiv Kawa, about his tool SQLRecon. Obviously, if you can execute SQL queries on a server, then you can dump all data that you have permissions to access, and this could be concerning if sensitive data is stored in the database. However, if you have privileged access to the SQL server, then you can execute code on the underlying operating system. Here are a few ways that you might do that:
This ultimately depends on the privileges of the user who created the connection, but if you’ve ever pivoted through a SQL server to achieve an objective, then you know how common over-privileged accounts are. Even if the connected user does not have the privileges to execute code, you can also check for impersonation, links to other SQL servers or credentials stored in cleartext in databases.
However, all of this is ultimately meaningless, since the “Execute a SQL query (V2)” action is not supported for gateways.
Other actions, such as “Get rows (V2)”, which will get the rows out of a specified table, work fine. We just can’t execute arbitrary queries on the server. I presume this is because Microsoft considered the possibility of abuse and decided that exposing the insecurities of on-premises SQL servers to external O365 users is bad.
If you look through all available actions for the SQL connector, you’ll spot the “Transform data using Power Query” action. Despite the name, Power Query is not a member of the Power Platform family of services. Rather, it is a data transformation engine that you can find inside other services/applications, like Excel. As a data transformation engine, Power Query is designed to take data in and transform it without modifying the source data.
After creating a “Transform data using Power Query” action with a valid connection, it will bring up a menu showing all the tables in whatever database it’s connected to. In my test SQL server, there’s just an empty table called “Persons”.
Selecting “Transform data” will bring us to the next screen, which is a Power Query editor. Power Query uses the M formula language, a data transformation language developed by Microsoft. The reference docs for the M language document the “Accessing data functions”, a list of functions that can be used to ingest data into Power Query. When we open our Power Query editor to the default query, we see that the “Sql.Databases” function is being used to grab information from the connected database.
After browsing through the 1,394-page PDF version of the M language, I noticed that the “Sql.Database” function (note the missing “S”) has an optional parameter called “Query”. This parameter is described as “A native SQL query used to retrieve data”.
If you pop the following Power Query code into the editor, a warning is displayed saying that “Native queries may be unsafe and alter the database”.
Well, “alter the database” is my middle name, so after hitting “Continue,” we’re rewarded with the output of a native SQL query.
Just to recap, here’s how you can abuse this to compromise an on-premises SQL server with nothing but access to a Power Apps license:
According to these Microsoft docs that were last updated in 2022, if you share an app that uses data from a gateway, then the gateway will be shared as well. From testing in my tenant, this no longer seems to be the case. That said, if you do have access to a gateway, then you can create new connections through it, which means you are no longer limited by the existing connections. This does mean that you need to have compromised plaintext credentials for AD or SQL accounts and know the hostnames of SQL servers, although it’s not uncommon to come across this info in SharePoint/Confluence.
You can also take advantage of other connectors that use gateways, such as the “File System” action. This also requires you to have valid credentials and hostnames, but it means you can read/write files on internal hosts.
If you get access to an account with Power Apps access, you’ll want to check all the environments that you have access to. You can see this by selecting the “Environment” drop-down in the upper right corner. In each environment, you’ll want to select “… More” and then “Discover All”. This will take you to a page where you can navigate to everything in Power Apps.
From there, you can select “Connections” to see any connections you have access to, and “Gateways” to see any gateways you have access to. You can also see who owns the connections, so you can check if the user is privileged or not.
Additionally, on the left side of the screen are the “Flows” and “Apps” buttons. You’ll want to hit “Shared with me” so that you can see everything, and you can begin to look for plaintext credentials or sensitive information. HTTP flow actions are particularly ripe for finding passwords and API keys.
Administrators should consider limiting which users can install gateways or disable them entirely if there’s no business use case for them. You can do this by going into the Power Apps admin platform, selecting “Data”, checking the “Tenant Administration” box and then selecting “Manage gateway installers”. From there, you can enable the “Restrict users in your organization from installing gateways” setting and add users who do need to install gateways. See Microsoft’s documentation for more information.
Consider periodically evaluating connections in your environment and ensuring that users are not widely sharing sensitive connections.
In this blog, we examined how a user with access to a SQL server connector using an on-premises data gateway can execute native queries on the server and potentially pivot from O365 to on-premises resources. The behavior that previously made this a common misconfiguration was changed in 2024, but with the right access, an attacker may still find themselves in a position to abuse this. With the release of this blog, we hope that defenders will audit their environment to identify gateways and overshared connectors to prevent future attacks targeting Power Apps.
2/10/2025: Original MSRC case submitted
2/11/2025: MSRC states that this is a social engineering issue and closes the case
2/12/2025: Second MSRC case submitted
2/24/2025: MSRC assesses vulnerability with Low severity
Gain insights to prepare and respond to cyberattacks with greater speed and effectiveness with the IBM X-Force threat intelligence index.
Learn how to navigate the challenges and tap into the resilience of generative AI in cybersecurity.
Understand the latest threats and strengthen your cloud defenses with the IBM X-Force cloud threat landscape report.
Find out how data security helps protect digital information from unauthorized access, corruption or theft throughout its entire lifecycle.
A cyberattack is an intentional effort to steal, expose, alter, disable or destroy data, applications or other assets through unauthorized access.
Stay up to date with the latest trends and news about security.