For most of us out there, conditional access is something we still either struggle with or have extreme inconsistencies when it comes to implementing policies across our customer environments. I would say that most environments still have some pretty significant security holes given misconfiguration of policies or a lack of understanding in the scope of what is being implemented. In this article, I am going to be breaking down:
- Key considerations for implementation
- Some common attacks that can get around MFA and how to protect against them
- My recommended conditional access policies
- Automation scripts to help you implement and monitor policies across customers (Conditional access as code)
Why your policies suck
Scope Constantly Changes
First, I didn’t write this blog post to cast any shade or say that I am the “master of conditional access.” Conditional access is complex! Your ideal target state is constantly changing because of the threat landscape and the additional scope that Microsoft keeps adding to the policies you can configure. Frequently I sign in to find a new setting in the policy configuration I have never seen before.
Uniqueness Of Client Environment
In a perfect world, we could have a baseline of conditional access policies we could implement in EVERY customer environment with little to no variance. The reality is far from that due to factors such as the following:
- Hybrid vs Cloud native environments
- LOB Apps
- On-Prem File Shares
- Office presence vs Remote/Hybrid work
- Geographic presence
- Regulatory Requirements (i.e. Hospitals, Schools, etc.)
- Operational maturity: Is MFA enforced?, Are devices enrolled into Intune?, Is device compliance enforced? What method of mfa is being used? Zero-trust or secure perimeter?
Change Management Gaps
Over time, we end up making changes or creating “exclusions” within our policies to overcome certain operational constraints. A great example of this is excluding some user or service account from MFA because it is blocking us from taking certain actions. In many cases, we don’t have a formal change management process around this, it is not documented, and we do not have any capacity to formally review these policies over time to detect this “drift” or deviation from what we would consider to be a compliant policy.
You don't invest the Time
There are many things that come out from Microsoft that waste our time (NCE cough cough). Spending time with Conditional Access is not one of those things. Investing time to implement strategy for conditional access across your clients is something you should 100% be doing today. If we think about the highest impact actions we can take to reduce our attack surface, I would argue that implementing strong conditional access policies is top of that list.
The Threat Landscape
There is certainly a laundry list of attacks and attack vectors (more to cover than in a single blog) but I wanted to provide some common examples of attacks we see in the wild today that Conditional access policies can help you protect against.
Credential Phishing
Users may have compromised credentials due to brute force attempts, password spray attacks, or some other type of credential theft where an attacker can gain access into an account simply by having a username/password combination. One of the most common attacks is a phishing attempt where a user clicks on a link, is taken to a malicious website disguised as a legitimate website, and has their credentials compromised as soon as they are entered. Enforcing MFA is most common way to protect against this type of attack.
Adversary-in-the-middle (AitM) phishing attack
Tools like Evilginx2 do more than just credential phishing by putting harmful infrastructure between the user and the real application the user wants to access. When the user is phished, the harmful infrastructure gets both the credentials of the user, and the token of that user which carries an MFA claim. This allows a user to compromise an account even where MFA is enforced. Elliot showed a great example of this in his video here: How hackers are breaking into MFA enabled Microsoft 365 accounts (youtube.com)
Also check out this attack path where a user leveraging MFA with number matching was still compromised: User Compromised When MFA (Number Matching) In Use : r/msp (reddit.com)
Pass-the-cookie attack
A type of attack where an attacker can avoid authentication controls by stealing browser cookies is called a “pass-the-cookie” attack. Browser cookies are used by web applications to store user authentication information. This way, a website can remember you and not ask for your credentials every time you visit a new page.
“Pass-the-cookie” is similar to pass-the-hash or pass-the-ticket attacks in Active Directory. When you authenticate to Microsoft 365 through a browser, a cookie is created and saved for that session. If an attacker can hack a device and get the browser cookies, they could use that cookie in a different web browser on another system, skipping security checks along the way. Users who are using personal devices to access corporate resources are especially vulnerable. The attacker does not have to know the compromised account password or even the email address for this to work— those details are held within the cookie.
QR-Code Phishing
Over the last few years QR Codes have seen a rise in popularity in legitimate use scenarios, in part due to COVID but they are now also one of the fastest growing type of email-based attack. A QR code can be easily manipulated to redirect unsuspecting victims to malicious websites or to download malware in exactly the same way as URLs, only by putting the URL in a more difficult-to-detect location.
Example of a phishing email (impersonating DocuSign) with a QR code:
Persistence Techniques
If an account is compromised using one of the above methods, attackers often look to perform certain actions like binding a new device to the account to satisfy future MFA requirements. They could simply add another device by going to the security settings and adding an new MFA method such as authenticator.
They can also join new devices to the network with these accounts if there are no protections in place.
Preventing these attacks: My recommended CA Policies
I want to stress that every environment is different and I am not saying by implementing the conditional access policies below, you will be fully protected. These are just some of the baselines I try to implement in all tenants:
Protections:
- CAE: Continuous access evaluation in Microsoft Entra – Microsoft Entra ID | Microsoft Learn
- Strict Location CAE: Continuous access evaluation strict location enforcement in Microsoft Entra ID – Microsoft Entra ID | Microsoft Learn
This conditional access policy allows you to configure trusted locations that are strictly enforced with conditional access policies. This policy would protect you in the examples of AiTM and pass-the-cookie attacks. If a users token or cookie were stolen, it would immediately block the attacker since they would be trying to access resources outside of a trusted location immediately. This provides more protections over traditional CAE as those policies where your default ttl for tokens is 1 hour.
Protections:
Require MFA for all users with Conditional Access – Microsoft Entra ID | Microsoft Learn
Pretty standard policy here that will enforce MFA in any location. Helps prevent against basic credential phishing attacks. This should be a non-negotiable policy in all tenants. I am not a fan of excluding trusted locations from this policy. You should train users that MFA is a common practice wherever they are.
Protections:
Require MFA for administrators with Conditional Access – Microsoft Entra ID | Microsoft Learn
I like this as a backup to our previous policy in case any users get excluded for some reason over time because of drift. Admins should not be active users signing in all of the time and accessing email. These should be service accounts bound by a separate pair of credentials.
Protections:
It should be your goal to get phishing resistant MFA such as FIDO2 keys or Windows Hello to all users across all companies but that is not exactly a realistic expectation at this point in time. A much more achievable goal in the interim is to try to enforce phishing resistant MFA with admins or even high profile users within the company. Start with Global admin accounts and work your way from there.
Protections:
Require MFA for guest users with Conditional Access – Microsoft Entra ID | Microsoft Learn
Don’t let guest users fall outside of your security standards. A guest user without MFA could easily lead to data loss or a more advanced social engineering attack given the interactions with users inside your org.
Protections:
Require MFA for Azure management with Conditional Access – Microsoft Entra ID | Microsoft Learn
Much like MFA for admins, this should be a redundant policy as a backup to your main MFA policy in case any unwanted exclusions get added over time. I am more protective over this platform given the damages that might result from someone accessing an azure subscription and spinning up resources (such as crypto-mining).
Protections
MFA shall be required to enroll devices to Azure AD | Tminus365 Docs
It is recommended to enforce MFA before a user can register or join their device to Entra ID. This ensures that compromised accounts cannot be used to add rogue devices to Entra Active Directory. Keep in mind: If the user is brand new, has not set up MFA, and tries to join a device out-of-the box, a temporary access pass will need to be provided which will allow them to fulfill the MFA requirement.
Block authentication flows with Conditional Access policy – Microsoft Entra ID | Microsoft Learn
Introducing a new phishing technique for compromising Office 365 accounts (aadinternals.com)
The Device code flow is another way in which attackers could leverage a QR code to get a user to sign in to legit Microsoft URL and captures an access token/refresh token via this authentication flow.
Protections:
Conditional Access – Block access by location – Microsoft Entra ID | Microsoft Learn
If credentials are compromised or if a token is stolen, preventing access from certain countries is a good way to limit exposure. In our use case of persistence, the attacker would still be prevented from logging in if they were trying to access resources from a country not on our list(i.e US only). Reminder that if you implement this policy in a customer environment, you want to make an easy way for users to submit “travel exceptions” so you can be proactive about legitimate users getting locked out.
Protections:
Block legacy authentication – Microsoft Entra ID | Microsoft Learn
Pretty standard policy here that blocks legacy protocols that support single-factor auth. Don’t let printers and scanners cause you to open up broader legacy authentication holes in your environment.
Protections:
High Risk Users Shall Be Blocked | Tminus365 Docs
High Risk Sign-Ins Shall Be Blocked | Tminus365 Docs
I usually create these as two separate policies for tracking purposes within the sign-in logs. Some people configure this policy where they have users reset their passwords if they are flagged as high risk but I prefer to be extra cautious here and just block the user so the team can ensure proper investigation of the account. Keep in mind that these policies require Entra ID P2 licensing.
Protections:
Managed Devices shall be required for authentication | Tminus365 Docs
Users should not be allowed to access corporate resources on personal devices or devices not enrolled into Entra/Local Ad. This will also prevent against both account compromise and persistence techniques. Users are also much more susceptible to getting breached on non-managed devices that do not have your additional protections in place such as AV/EDR/etc.
Protections:
Noncompliant devices shall be blocked from accessing corporate resources | Tminus365 Docs
This is one of the strictest conditional access policies you can enforce but provides a great deal of protection. I try to ensure that this policy is configured with regulatory clients at a minimum.
Protections:
Browser Sessions shall not be persistent for privileged users | Tminus365 Docs
If you leverage the Strict Access CAE policy I mentioned above this is less applicable but you should limit the sessions for admin users such as the Global Admin role to an hour. This is just reducing your attack surface more and avoid compromise on devices where global admins might be already logged in. Some recommendations out there say you should do this for all users but I think this is way too disruptive and you will make many of your customers angry if you do that.
Protections:
Grant controls in Conditional Access policy – Microsoft Entra ID | Microsoft Learn
App Protection policies should be created for mobile devices | Tminus365 Docs
If users want to access their corporate data on personal mobile devices, leverage app protection policies in Intune. They allow you to encrypt the corporate data, create save as/cut/copy/paste restrictions, allow you remotely wipe data off of the device (just the app not the entire phone). You should institute this policy to protect data on these devices.
Protection:
Don’t let users leverage the native mail client on their mobile device to connect to their corporate account. Force them to use the approved app store/google play store Microsoft apps so you can apply addition protections with app protection policies.
Other Key Tips
- Turn-on policies to report-only to begin – Monitor the impact to end-users and be proactive with communications before blindly turning on Conditional Access Policies in a tenant
- Use the same naming conventions – Use the same naming conventions in every tenant for these policies. That will make it easier to stay organized and also report on across tenants in the future. You can also append things like (NA) to the end of conditional access policies in your baseline that may not be applicable to a certain tenant because they do not have the licensing to enforce that policy or their environment is not the same.
- Use Deployment Rings – Think of deploying CA policies like patches to devices within an organization. You really want to have an “beta testers” group and so forth to test out the changes before going wide-spread. There may be something things you cannot garner from report-only mode. The champions in the beta testers group can also give you good feedback on messaging you might want to incorporate to a wide audience to help you avoid helpdesk calls/user friction.
- Reduce the decisions you need to make – There are some factors that increase the complexity of what you need to do to protect an environment significantly such as allowing personal devices to access corporate information. For me, no personal devices is a non-negotiable and it reduces the number of conditional access policies I would need to make significantly. Always try to define some core principles that allow you to reduce the complexity of what you need to configure in your conditional access policies.
Conditional Access As Code
The concept of managing conditional access policies as code has been around for years but I don’t see many people adopting it due to some barriers to entry from a technical perspective.
Effectively, you want to able to configure, manage, deploy, and monitor conditional access policies across your customers in an automated way to:
- Ensure proper change control
- Detect deviations or drift in policies
- Avoid misconfigurations due to human error
There are a few open source projects in this area that I really like:
This project allows you to easily deploy a set of conditional access policies (your baseline) to a tenant. It can be a great way to deploy your baselines in report only mode when you onboard a new customer.
This is another great project that allows you to manage the lifecycle of conditional access policies in a tenant. You can build, deploy, and backup policies in tenants. Additionally, it should you how to leverage an Azure Logic App to work approvals into your workflows.
Multi-tenant Reporting
I have also recently built a script that allows you to report on all of the conditional access policies across your customers. This leverages your GDAP relationships for the necessary permissions to pull this information in a single script. It outputs all of the policies across customers and their subsequent settings into a CSV:
NOTE: This does require the prerequisites of configuring your environment with the Secure application model to run these scripts. I outlined how to set that up in this blog post: My Automations Break with GDAP: The Fix! – (tminus365.com)
I have also created some PowerShell scripts that allow you to:
- Discover Licensed Users who are excluded from CA policies that enforce MFA: M365_Security/Get-CAPExcludedUsers.ps1 at main · msp4msps/M365_Security (github.com)
Conclusion and Next Steps
Here are the recommended steps I would take next to get the most out of this article:
- Document the conditional access policies in your customer environments today
- Define your MSP approved baseline of Conditional Access Policies.
- Use the proper naming conventions like I talked about so you can easily discover gaps in deployment of these policies with reporting in the future
- Test these baselines in your internal tenant.
- Update customer environments to reflect your baseline (Leave the policies you cannot turn on immediately into report-only mode)
- Create a project plan based on gaps to turn on CAP across customer environments.
- Put a formal change management process in place for the lifecycle of your conditional access policy baselines. At a minimum include:
- How users submit and approve new conditional access policies or updates to existing conditional access policies in the baseline
- How frequently you review the existing baseline (i.e once a quarter, once every 6 months, etc.)
- All Deviations/exclusions/exceptions to your baseline should be documented on a per customer layer.
- Put a formal process in plan to add your baselines to a customer tenant upon onboarding