If anyone is unlucky enough to read my previous blogs you will know I like to hack the Power Platform. That can be miss using features to genuine bugs/configuration issues. I really enjoy understanding how things work and problem solving (probably why I'm an engineer), and trying to identify hacking opportunities is a good way to scratch that itch. So today I wanted to go through the process I do when trying to identify vulnerabilities, and in this example Microsoft beat me.
There are the following steps:
- Identify the Permission you want
- How is that Permission granted
- What controls that Permission has
- Bypassing the controls
1. Identify the Permission you want
So in this case I'm looking into connections, they are the most valuable thing in the platform. I want to use someone's else's connections in my flow so that I can do things like.
- Read Emails
- Send/Approve Emails
- Access Secure Data
There are many different permissions you might want to look into, examples:
- Accessing environment with elevated DLP
- Read flow logs
- Edit production apps/flows
- Delete records I do not have permission too
2. How is that Permission granted
There are a few ways to share connections, but the most common is through sharing flows. If you share a flow with someone you are sharing those connections.
3. What controls are on that Permission
When building a flow I am only able to select my connections/connection references. The UI will not let me even select someone else's connection.
But if the other maker creates the flow and shares it with me then I can see their connections. Within the flow I am able to add new actions and use the connection.
But I cant paste that action into a new flow.
I also cant save a copy with the connections, it forces me to create a new connection.
So it appears there are lots of controls around the connection, with it linked to the flow.
4. Bypassing the controls
So here comes the hard bit, we understand the process, now we need to figure out where the weak points are. In my experience the Power Platform fails on 2 key security principles:
- PoLP (The principle of least privilege)
- Defence in Depth
PoLP is giving precise access, which can add complexity, so its often easier to give someone higher access then they need. Defence in Depth is about securing all levels, I have found that often just the UI is secured, with the api it calls not.
In this case I'm relying on both of the above, with users given higher permissions then they should and bypassing controls through api calls. I'm also targeting the change to the Platform, moving from non solution aware to solution aware. Connection references are different from the original connection, which was included in the flow. So maybe that break between the flow and the connection may be a vulnerability.
So here's my thought,
- I can share connection references as a system customizer/system admin
- The connection references has the connection in it
- Can I then create a flow through the api using the connection reference
When using the api I have 2 main tools:
- Browser Dev tools
- Postman
Browser Dev tools
Using the dev tools in your browser allows you to see what api's the Power Platform is calling and most importantly you can borrow the auth token (it expires quickly so you have to continually update it).
Postman
Postman is a api client that allows you to call any http(s) end point and view the response. There are multiple other clients too but Postman has become my go to.
Postman has environment variables that allow you to swap our urls and parameters without having to change the actual calls. They are shown by {{varName}}
.
So lets see if we can get access to someone's connections through a flow we create with their connection references. One big call out is the attacker would need elevated permissions in the environment (most likely a System Adin or System Customizer) that gives them full read/share access to the connection reference table.
List Users
First I query the systemuser table to return my systemuserid and the targets.
List Connections
I then use the targets systemuserid to query the connection references table, that way I can find the connection type I want and use those values when I create the flow.
Share Connection Reference
With the connectionreferenceid and my systemuserid I can share the required connection reference with me.
Create Flow
No I have all the pieces I need, I update my flow definition to use the connection reference data.
{\"properties\":{\"connectionReferences\":{\"shared_sharepointonline\":{\"connectionName\":\"{{connection}}\",\"source\":\"Embedded\",\"id\":\"/providers/Microsoft.PowerApps/apis{{connectorid}}\",\"tier\":\"NotSpecified\"}},
The json has to be converted to string in the api call.
Get Workflow
The flow should now be created but it is not turned on. So we query the workflows table with the flow name to return the workflowid.
Turn on Flow
Last step we Patch the flow using the workflowid, setting it to on.
{
"statecode": 1,
"statuscode": 2
}
And it didn't work...
I tried the UI too, but it looks like Microsoft was one step ahead. Sharing a connection reference does not trigger a sharing of the connection like it does in a flow. I also suspect that if I share a flow through the Dataverse API (like I did with the connection reference), it will not work too. There must be a different API running when you share a flow that shares the connection as well.
I also tried creating the flow with my connection, turning it on, and then updating the connection reference through a Patch, but again that didn't work too.
You can find my Postman collection here if you want to take a look,
And that's the thing about looking for vulnerabilities, most the times you don't find anything. But its a great exercise to gain valuable understanding on how the platform works. Experience that helps in normal development, and every so often you do find something, and that adds value globally, which is very cool 😎
Top comments (1)
Great insights!!!!