- Zenity Labs
- Posts
- The Power of One SSRF Vulnerability: A Multi-Platform Threat
The Power of One SSRF Vulnerability: A Multi-Platform Threat
Introduction
In this post, we’re disclosing a critical SSRF vulnerability within the SharePoint connector on Power Platform. Exploiting this vulnerability would allow attackers to harvest the user’s credentials, granting them access to send requests to the SharePoint API on behalf of the impersonated user, compromising sensitive data and executing unauthorized actions.
Sounds scary, right?
But wait, there’s more! This vulnerability can be exploited across Power Automate, Power Apps, Copilot Studio and Copilot365, which significantly broadens the scope of potential damage. It increases the likelihood of a successful attack, allowing hackers to target multiple interconnected services within the Power Platform ecosystem. The cross-platform nature of the issue also enhances an attacker’s ability to maintain persistence within the organization and stay undetected for extended periods.
Background
The core issue lies in insufficient input validation within the SharePoint connector. This flaw allows malicious actors to use the "custom value" functionality to insert their own crafted URLs. Instead of detecting invalid or incorrect patterns for the SharePoint site, the connector accepts the input and sends the request directly to the specified server.
And this is where the danger lies... By exploiting the classic SSRF vulnerability, we observed that the SharePoint token, which the flow uses to authenticate itself with the service, was also sent along with the request. After thoroughly examining the token, we confirmed that it was the flow creator's token. This token can then be used outside the platform with a simple cURL or Burp Suite request to make API calls.
This led us to ask the question: "What if there were another user connection, and we could send this request on behalf of the user we granted access to?"
And this is where our PoC begins…let’s roll up our sleeves and dive into it!
Prerequisites
To perform this attack, you need both the Environment Maker role and the Basic User role in Power Platform. The Environment Maker role allows you to create apps, flows, and connections, and share them with others in your organization. The Basic User role enables you to run apps and interact with records you own (e.g., Account, Contact).
Basically, this combination of permissions is all you need to get started with the attack and implement it effectively.
PoC: Uncovering the Exploitation Technique
Now that we've outlined the potential risks, let’s dive into the heart of the matter - the Proof of Concept (PoC). In this section, we'll uncover the technical details of how this SSRF vulnerability is exploited and why it poses such a significant threat. By demonstrating how easily attackers can manipulate the SharePoint connector, we’ll highlight the severity of this flaw and its potential impact on organizations using Power Platform services.
Step 1: Creating a Simple Flow
We begin by creating a simple flow using the "List folder" SharePoint action, as shown in the screenshot below.
The configuration of the SharePoint connector is straightforward. Instead of providing a valid SharePoint site URL, you can enter the URL of a server of your choice, which you potentially control.
For this demonstration, We used a Burp Collaborator address - a dynamic DNS service that allows security researchers to detect and analyze incoming HTTP, DNS requests. This helps confirm whether a payload successfully triggered a response from the target system.
Step 2: Sharing the Flow
Next, we navigate to the flow management interface and share the flow with another user. You can assign them as either a co-owner or a low-privileged user.
From an attacker’s perspective, it’s critical to assign the user as a low-privileged user. This ensures they cannot modify the flow’s behavior or configuration. While this step is not strictly necessary for demonstration purposes, it is crucial in a real-world attack scenario. A low-privileged user will be unable to change the "Connection Used" configuration from "Provided by run-only user" to "Use this connection (<connection_name>).
For successful exploitation and token leakage, we aim to force the user to provide their own connection when interacting with the flow. This ensures that the flow uses the token associated with their credentials, enabling the attacker to obtain it.
The setup for this section is illustrated in the screenshot below.
Step 3: Victim Runs the Flow
The victim, with whom the flow has been shared, logs in and attempts to run the flow in order to list the contents of the SharePoint folder.
Reminder: As a low-privileged user, the victim cannot inspect the flow’s actual logic or view how the connection is configured. This lack of visibility ensures that they remain unaware of any malicious behavior.
Meanwhile, on the attacker’s side, Burp Suite alerts us with several hits. Let’s investigate what we’ve captured.
In the Inspector tab, we highlight a unique name value located within the "payload" part of the decoded JWT token. This strongly indicates that we’ve obtained the token of the user with whom we shared the resource. In this particular case, it’s the Power Platform admin’s token.
Step 4: Investigating the Token’s Audience Claim
Let’s analyze what this token represents, how it can be leveraged, and where it can be used to escalate access or perform further actions.
By examining the "aud" (audience) claim in the captured token, we find the value "00000003-0000-0ff1-ce00-000000000000."
A quick Google search reveals that this audience ID corresponds to SharePoint.
Sounds like success! This confirms that the token is valid for accessing SharePoint resources, paving the way for further exploitation opportunities.
Step 5: Using the Token Outside the Platform
Let’s take it a step further and attempt to use the captured token outside of the Power Platform.
Using tools like cURL or Burp Suite, we can make API calls directly to SharePoint, acting on behalf of the user whose token we’ve stolen.
The simplest example of making a request to SharePoint APIs with the stolen user’s token is illustrated in the screenshot below. Here, the SiteUsers endpoint is used, which retrieves the collection of all users that belong to the site collection. This demonstrates how an attacker can enumerate users within a SharePoint site using the compromised token.
Isn’t that cool?!
What we've seen so far is just the tip of the iceberg. Imagine a more complex, real-world scenario where this vulnerability leads to massive token leakage.
By chaining similar flaws across interconnected Power Platform services, attackers could harvest tokens from multiple users, escalating their access across the organization and creating a ripple effect of security breaches.
Let’s move to the next part of our PoC!
Power Apps
It all starts in a similar way: by creating a vulnerable flow. The setup of the flow is essentially the same as in the previous part, with one key difference. Now, we don’t need to share our flow with another user.
Step 1: Flow configuration
Create a flow with the Power Apps trigger and the "List folder" action from the SharePoint connector.
Use your proxy server as the Site Address within SharePoint.
As mentioned earlier, there’s no need to share the flow at this stage. The flow setup is complete at this point.
Step 2: Canvas App configuration
Now, let’s move on to Power Apps and create a simple Canvas app. In a real-world scenario, you’d want to mimic a valid resource in order to harvest as many tokens as possible and maintain your "spot" within the organization for as long as you can.
So, we created a sleek-looking app and embedded our flow into it.
Now, let’s try to hide the function that triggers our flow within the app’s functionality. For this demo, we created an "Employee Survey" app and embedded the flow trigger at the very end of the survey. This minimizes the chances of being caught, as it would look suspicious if the user encountered any errors or other signs of malicious activity at the beginning of the survey.
Now that everything is set up, it’s time to share it with our victims. In a real-world attack, this could be distributed across the entire tenant, allowing the attacker to target a large number of users and harvest tokens more efficiently.
Step 3: The Victim Takes the Bait
Our victim has logged in and is now ready to take the survey.
They are running the application.
This is what the victim sees when they launch the app. They are presented with a consent prompt asking for permission to access their connections. Essentially, the app is requesting approval to perform actions on behalf of the user, such as accessing their SharePoint resources, which are linked through a Power Automate flow.
And here is a very important step for a successful attack: the user must approve it to proceed using our malicious app. Without this approval, the attack cannot continue. It's at this stage that a suspicious user could prevent the attack by denying access.
The victim has granted the app permission to access their connection and has begun taking the survey. They proceed through the last two questions:
"Do you see yourself working here in one year?" - They definitely click “Yes”.
"Other comments?" - They leave it blank, responding with "No comments" and press the "Next" button to continue.
Done!
The final screen of the app indicates that the survey was successfully completed.
Of course, every action taken by the attacker leaves a trace, and this case is no exception. After completing the survey, an error appears that could seem suspicious to someone familiar with the specifics of Power Platform. In such cases, the user might report the error to an admin, and the attacker could get caught. However, due to human nature, many people simply disregard these errors or don't take them seriously, allowing them to pass unnoticed.
The small reddish notification that popped up: 'employee_survey_flow.Run.failed: {"error": {..."message":"BadGateway"...}' This essentially means that the flow ran with an error, but considering the specifics of the SharePoint connector vulnerability, we don’t actually need a '200' HTTP response for successful exploitation. Believe me, their token is already waiting for us in the Burp Collaborator.
As we mentioned, it’s right here - look at it. We don’t need to go over the token investigation again, as we covered that in the previous PoC section.
Once again, success.
You can take this even further by embedding the Canvas app into a Teams channel, for example. Once users interact with the app in Teams, you can harvest their tokens just as easily, expanding your reach across the organization and making the attack even more widespread.
Now, let’s move on to the next platform - Copilot Studio.
Copilot Studio
Step 1: Create the Copilot Agent
To start, we’ll create a Copilot agent with meaningful description and instructions. The specific configuration of the agent isn’t as important as one key step: you need to add the vulnerable SharePoint action.
As we’ve done before, let’s add the "List folder" action to the agent, ensuring it’s connected to the same vulnerable SharePoint connector.
Step 2: Configure the Action
Now, click on the "List folder" action and let's configure it.
Head over to the "Inputs" tab, which is where we can replace the valid SharePoint site address with our Burp Collaborator URL.
Step 3: Bypassing the URL Validation
This part may seem a bit tricky because you can’t just type in the URL directly in the "Value" field. Every time you enter a non-valid URL, it gets replaced with the URL of your actual SharePoint site. However, we can easily bypass this behavior.
Click on the "three dots" in the top right corner of the page to access additional functionality. From the menu, select "Open code editor." This looks like exactly what we need!
Now that we have the code visible, we can see under the "inputs" object the "value" field, where we can place our Burp URL. Once we’ve done that, click "Save" to save the changes. Everything worked smoothly! Now, let’s proceed.
Now that we’ve fully set up our vulnerable Copilot agent, it’s time to share it with someone and test if it works as expected.
Step 4: The Victim Takes the Bait
The victim logged in and wants to test the functionality of our "SharePoint Content Assistant" agent. The conversation begins with a simple request: "Hi! Show me the content of /Documents." However, Copilot throws an error: "Additional permissions are required to run this action. To proceed, please select 'Connect' and review any missing connections."
"Okay—gotta do it." The user then presses the 'Connect' button.
They establish their connection and grant access to it for the Copilot agent.
They click "Submit" to proceed.
Let’s revisit the second part of the error that Copilot threw to the user:
"Once you have made these updates, please select 'Retry'..."
Well, the user has already established the connection, so they click "Retry."
But then, another error appears:
"Error message: The connector 'SharePoint' returned an HTTP error with code 400."
Note: It’s important to understand that even small errors, which may seem unrelated to your activities, can still pose a danger. As a user, you should always remain cautious, especially when resources are spread across your organization. There’s always a chance that someone may attempt to abuse your trust. This case is no exception. Had this error been reported in a timely manner, the malicious resource would have been detected and deleted by the admin (though this wouldn’t have saved our victim from the token leak). However, further exploitation of the malicious Copilot agent would have been prevented.
But we already know something has happened! Let’s check Burp Collaborator to confirm that the token was leaked.
And there it is. Success.
And here's the cherry on top, guys!
You can take it a step further - embed this agent into Copilot 365 and let the entire organization unknowingly use your malicious agent. By doing this, you can spread it across the organization, allowing you to harvest tokens and escalate your access on a much larger scale.
And we did exactly that…
Copilot 365
First, we published our malicious agent and shared it across the organization.
To get it visible in Copilot 365, you'll need approval from an admin. Once that’s done, all you have to do is install the agent - your malicious agent is now embedded, ready to go to work.
Starting the Conversation with Your Agent
Now that the agent is embedded and ready to go, it’s time to start the conversation with it. Simply initiate the conversation with your agent, just like you would with any other Copilot assistant. In this case, you can prompt it with a simple request, like “Hi, show me the content of /Documents.”
Step 2: Grant Permission to Proceed
As the user interacts with the Copilot agent, they are prompted with a consent message. To allow the Copilot agent to access SharePoint resources, they will need to grant permission. The message typically states:
"OK, I'll connect to SharePoint Content Assistant to process your query. Returns files contained in a SharePoint folder."
The user can then click on the "Allow once" button, which will give the agent access to retrieve the SharePoint data necessary for the request.
Step 3: Signing in to the Agent
After granting permission, the Copilot agent will prompt the user to sign in to proceed with the request. In this case, it says:
"Hi Kris! Let me check the contents of the /Documents folder for you. Please sign in to SharePoint Content Assistant to proceed. Upon successful login, we’ll promptly start processing your query."
The user will click on the "Sign in to SharePoint Content Assistant" button to authenticate and give the agent access to retrieve the requested SharePoint data.
Once the user clicks "Sign in to SharePoint Content Assistant" they are taken through the process of establishing a connection to the SharePoint service. The steps are familiar, just like in the Copilot agent section:
The user sees the "Manage your connections" page, where they find SharePoint listed with the status "Not Connected."
They click "Connect", and the next screen prompts them to either select an existing SharePoint connection or create a new one.
The user clicks "Create or pick a connection" and picks SharePoint from the available list.
Once the connection is established, repeat the task that was previously given to the agent.
Step 4: Prompting the User to Retry
When the user retries the request, they encounter the following error:
"It seems there was an error while trying to access the contents of the /Documents folder. Please try again later or check if the folder path is correct. If you need any further assistance, feel free to ask!"
But we already know something happened!
We open our Burp Collaborator and—voilà! The token has been leaked, confirming our success.
We’ve just demonstrated how to "poison" four (actually five, if you count Teams) platforms with a single vulnerable element. The impact? Well, it’s pretty huge. Once you understand the vast attack surface, it’s clear how a hacker or a rogue insider could have a field day with this kind of knowledge.
Disclosure Timeline
Once we discovered the vulnerability, the report was immediately sent to Microsoft.
The report was created and submitted on 19th September 2024.
The case for the issue was opened on 20th September 2024.
It remained in the Review/Repro stage until 8th October 2024.
The behavior was confirmed on 10th October 2024.
The status was updated to Pre-Release on 22nd October 2024.
On 24th October 2024, we received confirmation that the case was eligible for the Bounty Award.
After the assessment, the case was classified as having "important" severity with an "Elevation of Privilege" security impact.
On 13th December 2024, the fix was reported.
The exploitation of the SSRF is not available anymore.
We’d like to thank Microsoft for their quick response to our report and their swift action in addressing the issue.
Conclusion
We’re still excited about this discovery. Just imagining how many problems this vulnerability could cause, especially when you consider how widely the Power Platform ecosystem is used - and particularly how many organizations rely on the SharePoint connector daily (and we know that number is high!).
Given the potential impact of the vulnerability, we’re thrilled to have had the opportunity to prevent dozens of organizations from experiencing token leakage, which could have led to unpredictable consequences, and to help protect the "online" landscape.
Thank you for your attention. Stay tuned, and see you next time!
Reply