How often do you check and track the Apps list or the app permissions in Enterprise apps in Microsoft Entra? Is that only when you need to register or create a new app? How about user-installed apps? What controls do you have on users’ consent on apps? Or know what apps are making excessive calls to EWS when the user is working in the app?
The goal of this article is to go through the OAuth 2.0 flow and to show how it’s different from a standard Gallery app in Entra ID, and how it can stay rogue with high privileges, and how to detect them and take control of your apps landscape.
- In General
- In Simple Terms, How Does OAuth 2.0 Work?
- Application Objects and Service Principles
- A Possible Attack Kill-Chain in a Tenant with Poor Security Controls
- Importance of knowing the apps Landscape – Closing Gaps
- Overpermitted OAuth Apps
- Users Installing Their Own Apps
- App Governance in Defender for Cloud Apps
- App Connectors
- OAuth Apps at a Glance
- App Policies – Taking Action
- Anomaly Detection – Cloud Apps – Policy Management
- KQL – Threat Hunting
- Wrapping Up
In General
No, my users can’t install any apps. It’s being protected by other policies. While that statement is true, there can be Web-apps that require user permissions to different components to operate. They don’t necessarily need to be installed on the device. OAuth apps, to be precise. These apps are often coming from another service provider or use Entra user details to authenticate the user to another system. When authorizing occurs, this system is requesting access to some components, as mentioned earlier.
From the user’s point of view, this is easy for them as they don’t need to authenticate to another system. They just need to provide their consent for the service provider to access the components on their behalf, and they are in.
However, this can be a nightmare to the IT Admin if they are not on top of their Entra Admin portal activities. OAuth app permissions can be one of them.
Rogue app request for consent? 🫣
We are all familiar with a message like below. As you can see, the end user is presented with a consent form from an app that they are trying to access, which is trying to request access to some components on behalf of the user.

In Simple Terms, How Does OAuth 2.0 Work?
- User (client) requests access to the resource (Web App) that is controlled by the resource owner.
- The resource (Web App) is located on the resource owner’s end, which is not in the same Entra portal
- Webapp redirects the request to the authorization server (Entra ID (IdP))
- Entra ID requests the user to authenticate against it (this is where it validates user access in Entra against Conditional Access Policies, etc.). Once it’s validated,
- The IdP issues the Access Token and the Refresh Token
- Access Token – This contains the permissions granted by the IdP.
- Refresh Token – Access Token typically expires in 1 hour. Refresh token makes sure it will request new access from the IdP.
- Web browser redirects the received Access token to the Web App.
- Web App validates access and sends the required page to the user.

Application Objects and Service Principles
Any app that’s in Entra ID will have to register in Entra ID. There are two types of objects that are created when the app is registered. Application Object and Service Principal Object.
- Application Object – Will be populaed under App Registrrations – this is where you setup App permissions and etc.. This can be an app you arre develping as well.
- Service Principle – Will be populated under Enterprise Applications – Where you use it for functions like CA Policies, app access, etc. This can be an app you are creating via the Entra ID App gallery.
Typically, apps created using the Entra ID App Gallery use SSO in most cases and use SAML/ WS-Fed instead of OAuth. Check the example below when I try to create the “Box” app straight from the Entra App gallery.
In this situation, the authentication (not Authorization) works differently. When the user is trying to login to the connected app, the app redirects to Entra using a SAML request. Entra then validates the app access for this user and completes the authentication flow. This is the standard SSO flow.

Protocol | Purpose | Token Type |
---|---|---|
OAuth 2.0 | Delegated API access | Access token (JWT) |
SAML 2.0 | Authentication + SSO | SAML assertion (XML) |
So in a nutshell, OAuth 2.0 that runs with the Open ID Connect framework, requests access on behalf of the user, so the user (Just enough access in most cases) authorizes an app or a service.
Whereas OAuth 2.0 + OIDC which is named as Modern Auth, call APIs on user’s behalf (read, write permissions) and maintains the session securely.
Now that the terminology is sorted, let’s see where the problem is.
A Possible Attack Kill-Chain in a Tenant with Poor Security Controls

Step | Description | Who’s Involved |
---|---|---|
1 | Attacker registers a malicious app with broad Microsoft Graph API permissions (e.g., Mail.Read , Files.Read.All )Phishing email is sent with a crafted OAuth consent link, disguised as a trusted service or file |
Attacker |
2 | User clicks the link, which redirects them to the official Microsoft login/consent page User signs in (if not already authenticated) via Entra ID |
User |
3 | Microsoft displays a consent prompt, listing requested permissions | Entra ID |
4 | User grants consent, clicking “Accept” and unknowingly approving malicious app access | User |
4a | User receives the phishing app access | User |
5 | Access token (and refresh token) is issued to the attacker’s app | Entra ID |
6 | Token is received by attacker’s app via redirect URI | Attacker |
7 | Malicious app uses token to access Microsoft 365 resources (e.g., emails, OneDrive, Teams chats) via Graph API Attacker harvests sensitive data silently without further user interaction (esp. with offline_access ) |
Attacker |
Step 7 Explained

Importance of knowing the apps Landscape – Closing Gaps
As you can see above, the Authorization flow is working according to the industry standards. However, there are a couple of things that may get overlooked in an organization.
- Over Permissioned apps
- Risky Apps with misleading details
- Users installing their own apps
The good news is that you can close these security gaps. Let’s go one by one.
Overpermitted OAuth Apps
This is where the app requires access to Microsoft Graph, not just for User.Read.All types of permissions, but maybe User.Read.Write.All types of permissions. Or maybe access to the mailbox to send emails on behalf of the user.
Advise: It is always best to understand the permissions the app requires before registering it in Entra. And always question why you need to set up that many permissions. Maybe the app doesn’t need everything, but the developer does that as a safety net so the app will not stop working due to permissions. This is not a good sign at all as if the app was compromised, the adversary can easily take control of what he requires.
Users Installing Their Own Apps
This should be restricted from the get-go. This is basically providing a standard user with too much power to consent to apps that sometimes can lead to bad actors gaining access to resources. Technically speaking, there should be a process to get a Web App approved to use in the organization, and that includes the authentication method that includes API Permissions that come with the app.

Make sure you have set up Do not allow user consent – An administrator will be required for all apps option.

Result

You can set the users to request Admin Consent, and reviewers to check and grant it and set expiry for the grant, which is a good option

Since the bad actors are always trying ways to mislead the users by sending links with OAuth 2.0 consent requests, it is always important to check the blue tick that implies the App publisher (resource owner) is verified by Microsoft, even if you have blocked users providing consent.

The problem is the permissions requested by the resources when the client tries to access the apps. Or a malicious actor pushes a URL via an email, where the user clicks to consent to their permissions. These apps are not components that download into the endpoint that covers from the controls set by PUA, AppLocker, WDAC and in most cases by the Defender SmartScreen.
This app can be a standard web app that runs in the web browser of the computer or a mobile app that requests access to login.
Typically, the end user is not aware or does not have a deeper understanding of the permissions on a greater level. All they need is to access the specific app or the service.
App Governance in Defender for Cloud Apps
Defender for App Governance is a purpose-built feature for managing OAuth apps in the environment. Once the Defender for Cloud Apps + Defender for Endpoint integration is done and the App Connector is configured, this will start monitoring the OAuth apps, where you will be able to make informed decisions.
App Connectors
To be able to start monitoring the apps, Microsoft 365 App Connector in Defender for Cloud Apps needs to be configured to capture the Entra ID OAuth apps.


OAuth Apps at a Glance
Assets > Applications > OAuth Apps

I’ve taken an example below to show the permissions of the app.

Or, simply go to
Cloud Apps > App Governance >

App Policies – Taking Action
Banning the apps, understanding the permissions used by the app, or understanding what calls it’s making into the files, emails and etc., is important. App Policies in Defender for Cloud apps help you to check those, block apps then and there, and allow only the required apps to the users.
App governance > Policies will have some built-in policies where you can edit or App policies can be created based on Usage, Permissions, Certification, Activity, or as Custom.
I love the built-in policies where they have discussed every aspect of the malicious things that an app can do.

I want to show a policy based on Permissions > Overprivileged app


Anomaly Detection – Cloud Apps – Policy Management
A few OAuth Apps-related policies are sitting in Cloud Apps > Policies > Policy management section as well.
Policy name | Policy description |
---|---|
Misleading OAuth app name | Scans OAuth apps connected to your environment and triggers an alert when an app with a misleading name is detected. Misleading names, such as foreign letters that resemble Latin letters, could indicate an attempt to disguise a malicious app as a known and trusted app. |
Misleading publisher name for an OAuth app | Scans OAuth apps connected to your environment and triggers an alert when an app with a misleading publisher name is detected. Misleading publisher names, such as foreign letters that resemble Latin letters, could indicate an attempt to disguise a malicious app as an app coming from a known and trusted publisher. |
Malicious OAuth app consent | Scans OAuth apps connected to your environment and triggers an alert when a potentially malicious app is authorized. Malicious OAuth apps may be used as part of a phishing campaign in an attempt to compromise users. This detection uses Microsoft security research and threat intelligence expertise to identify malicious apps. |
Suspicious OAuth app file download activities | Scans the OAuth apps connected to your environment and triggers an alert when an app downloads multiple files from Microsoft SharePoint or Microsoft OneDrive in a manner that is unusual for the user. This may indicate that the user account is compromised. |
Unusual ISP for an OAuth App | This policy profiles your environment and triggers alerts when an OAuth app connects to your cloud applications from an uncommon ISP. This policy may indicate that an attacker tried to use a legitimate compromised app to perform malicious activities on your cloud applications. |
KQL – Threat Hunting
As always, you can use KQL to perform advanced threat hunting.
Noticed the OAuthAppInfo table, which is in Preview at the time of writing,g and this has some great info to dig more into apps and understand the nature of it.
https://learn.microsoft.com/en-us/defender-xdr/advanced-hunting-oauthappinfo-table
OAuthAppInfo
| project Timestamp, AppName, AddedOnTime, PrivilegeLevel, AppOrigin, Permissions, IsAdminConsented

And the CloudAppEvents table to get more info on OAuth apps
CloudAppEvents
| where ActionType == "Consent to application."
| project Timestamp, Application, ObjectName, AccountType, IsImpersonated

Wrapping Up
Setting up expiring Admin consent is ideal because it provides Admin Consent, and that can lead to accessing sensitive items in the Microsoft 365 ecosystem.
Combining the apps with Conditional Access Policies to better control the app activity.
So, to close this, as I mentioned previously, OAuth apps can be targets, and bad actors can easily break into the environment if the controls are not put in place to guard the app’s infrastructure and the activities and App Governance is vital!
Discover more from EMS Route
Subscribe to get the latest posts sent to your email.