We keep seeing a recurring pattern in our engagements. An organisation has configured device filters in Conditional Access as a security control to help with end user experience. They've picked their platforms, blocked non-compliant devices, and ticked the boxes. Then we review their policies using SuiteAuth Toolkit and expose significant gaps in their MFA policies caused by an over-trust in the device identity and a lack of a baseline MFA policy.
No exploits. No zero-days. Just a user agent string and an understanding of how Entra ID evaluates what device you're using.
This post covers the three bypass patterns we run into most often, and what to do about them. If you only remember one thing from this article: a baseline MFA policy with limited exclusions is the single most important control you have in your tenant, and no amount of device filtering makes up for not having one.
How does Entra ID actually know what device you're using?
Most admins we talk to assume there's some kind of deep inspection going on behind the scenes to determine the device a user is using. Unfortunately, that isn't the case.
When you set a Device Platform condition, Entra ID has two options to determine the platform. First it uses the Operating System if a device signal is present (e.g. from a PRT). Otherwise it falls back to reading the User Agent string from your browser. Your browser tells Entra "I'm Windows" and Entra believes it. The problem: both the User Agent string and the Device Operating System are self-reported.
If you implement a more in-depth Device Filter, Entra queries the device object registered in the directory and checks its attributes. If the device isn't registered at all, every attribute comes back as null.
These two mechanisms are completely independent. The gap between them is where all three bypasses live.
Device Platform condition → Read from Registered Device [when present] (self-reported, unverified)
Device Platform condition → Parsed from User Agent string (self-reported, unverified)
Device Filter condition → Checked against registered device objects in Entra ID
Unregistered device → All device properties = null
Here's how the platform detection actually works:
If an attacker sends a User Agent that doesn't match any platform you've written a policy for, no policy applies. They're in. If they register a device in an OS you aren't targeting, they're in. In both cases, Microsoft is making a best-effort guess on what platform the user is using.
Bypass #1 — Spoofing the User Agent
This is the easy one, and we demo it on almost every Microsoft Entra ID Conditional Access Review engagement.
What the client had: A Conditional Access policy requiring device compliance for Windows and macOS devices hitting M365.
What we did: Opened SuiteAuth, set up an Interactive OAuth, changed the User Agent to a Linux string, and watched the simulation run. Entra ID saw a Linux device. There was no policy covering Linux. We were in.
Ten seconds of work. The sign-in logs dutifully recorded "Linux" as the platform, and unless someone was watching for that, nobody noticed.
Microsoft's own docs say it plainly:
Conditional Access identifies the device platform using information provided by the device, such as user agent strings. Because user agent strings can be modified, this information isn't verified.
And on their page about blocking unsupported platforms, they repeat the warning:
The device platform condition is based on user agent strings. Conditional Access policies using this condition should be used with another policy, like one requiring device compliance or app protection policies, to mitigate the risk of user agent spoofing.
The platform condition is a hint. It was never meant to be a security boundary. Treating it like one is the mistake.
Bypass #2 — The null problem with unregistered devices
This one is sneakier, and it catches admins who think they've written solid filter rules.
The setup: An admin writes a device filter to block anything where device.operatingSystem doesn't equal "Windows". Sounds reasonable. Only let Windows devices through.
The problem: A personal laptop that's never been registered in Entra ID has no device object. All its properties are null. And null doesn't equal "Windows", so the filter matches and... does what, exactly? That depends on how the policy was built, and this is where people get tripped up.
Microsoft spells this out in their device filter docs:
For a device that is unregistered with Microsoft Entra ID, all device properties are considered as null values and the device attributes cannot be determined since the device does not exist in the directory.
And their recommended workaround:
The best way to target policies for unregistered devices is by using the negative operator since the configured filter rule would apply.
— Same page
Here's the practical difference:
| What you want | How you configure it | Registered non-Windows device | Unregistered device |
|---|---|---|---|
| Block non-Windows | Include where OS ≠ Windows | ✅ Blocked | ⚠️ Slips through |
| Block non-Windows | Exclude where OS = Windows | ✅ Blocked | ✅ Blocked |
The second version works because the exclusion only fires for devices that positively match "Windows". Everything else — including devices with null properties — stays in scope and gets blocked.
This is sometimes called the "double negative" pattern. It feels backwards when you're writing it, but it's the only way to catch unregistered devices:
- Want to block something? Use: Exclude + positive operator
- Want to allow something? Use: Include + negative operator
If you use a positive operator in an "Include" configuration for a blocking policy, unregistered devices will always slip through. Every time.
Bypass #3 — The bait and switch
This one combines both previous weaknesses. It's one of the more interesting pattern we run during assessments, and it's the reason we built our simulation tooling in the first place.
What the client had: Only Windows with Intune Compliance can access Microsoft 365 off the trusted network. Registering a Windows, iOS, or Android device requires Phishing Resistant MFA.
What we did:
The problem? They didn't require MFA for All Platforms to register a device. Leading to some sneaky MFA bypasses.
We ran a demo which lets us spoof any User Agent to Entra ID and register arbitrary device configurations to Intune.

First, we get an access token using a platform type nobody wrote a policy for (Linux). We use that token to register a Windows device. MFA would normally be required, but by using the bait-and-switch we are never prompted for it.
We can see that the spoofed User Agent is displayed in the Entra sign-in logs, the device is not compliant, and not managed:

Then, from that initial authentication, we register a spoofed Windows device and enrol it in Intune for compliance. The SuiteAuth timeline on the right shows each step of the chain: authentication challenge, token exchange, device registration with Entra ID, primary refresh token acquisition, Intune enrolment, and finally the compliance check-in completing successfully:

The gap between "what platform does the browser say it is" and "what device is actually registered in the directory" is a real architectural seam. These are two different trust signals and Entra evaluates them independently.
After a few moments of waiting (Intune can be a little slow to reflect the check-in) we can now start downloading all that user's data. Let's check their emails, files and chats:

Catching the bait and switch in your logs
So you've read this far and you're wondering: would I even notice if someone did this in my tenant? Probably not, unless you're specifically looking for it. But the telemetry is there. It is up to you to stitch it together.
The bait and switch leaves a distinctive trail across two separate log sources: SigninLogs and AuditLogs. The problem is that most SOC teams look at these independently. When you correlate them, the pattern stands out.
Here's what the attack looks like from a log perspective:
What to hunt for
The smoking gun is a platform change + new device registration from the same user in a short window. A user who signs in on Linux (or an unknown platform) with no CA policy applied, and then shortly afterwards registers a brand new Windows device that gets marked compliant. That doesn't look like the average Tuesday onboarding.
Here's a KQL query to scratch the surface of this pattern. It looks for users who had a sign-in followed by a device registration event from the same user within 1 hour which doesn't have a matching operating system (it's not perfect):
// Step 1: Sign-ins
let Signins = SigninLogs
| where TimeGenerated > ago(30d)
| where ResultType == 0
| project
SigninTime = TimeGenerated,
UserId = UserPrincipalName,
SigninPlatform = tostring(DeviceDetail.operatingSystem),
SigninIP = IPAddress;
// Step 2: Device registrations
let DeviceRegistrations = AuditLogs
| where TimeGenerated > ago(30d)
| where OperationName == "Register device"
| extend TargetUser = tostring(InitiatedBy.user.userPrincipalName)
| extend RegPlatform = tostring(AdditionalDetails[3].value) // OS reported during registration
| project
RegTime = TimeGenerated,
UserId = TargetUser,
RegPlatform,
DeviceName = tostring(TargetResources[0].displayName),
RegIP = tostring(InitiatedBy.user.ipAddress);
// Step 3: Join and flag platform mismatches
Signins
| join kind=inner DeviceRegistrations on UserId
| where RegTime between (SigninTime .. (SigninTime + 1h))
| where not(SigninPlatform startswith RegPlatform)
| project
SigninTime,
RegTime,
TimeDelta = RegTime - SigninTime,
UserId,
SigninPlatform,
RegPlatform,
DeviceName,
SigninIP,
RegIP
| sort by TimeDelta ascIf this returns results, pay attention to a few things:
- IP mismatch between the sign-in and the registration. If someone signs in from one IP on Linux and registers a device from a different IP shortly after, that's suspicious. In a legitimate scenario (someone setting up a new work laptop), these would normally be the same IP.
- The time gap. A genuine user getting a new device might register it the same day they sign in. But if the gap is very short — minutes rather than hours — and the platform changed, that looks more like an automated attack chain than someone unboxing a new Surface.
- Device names that look generic or auto-generated. Tools like ROADtools and similar leave telltale signs in the device object. Look at the device name, OS version strings, and user agent in the audit logs. A ROADtools registration will often show
Microsoft.OData.Clientas the user agent.
So how do you build policies that actually hold up?
We've broken three things. The answer is a pyramid of controls with a foundational baseline MFA policy at the base. Then you build mitigating controls on top.
Each layer catches what the one below it misses. MFA is the wide base — it applies to everyone and stops the most common attacks. The platform catch-all narrows things further. Device compliance filters out anything unmanaged. And at the top, the tightest control: admin accounts pinned to specific physical machines.
Start with MFA. Apply it unconditionally.
This is the one we argue about with clients the most, and the one we're most insistent on.
Your MFA policy should have no conditions attached to it. None. No platform filters, no trusted location exclusions, no "skip if device is compliant" carve-outs.
Every condition you attach to an MFA policy is something an attacker can spoof. Exclude a trusted location? VPN. Exclude a platform? User Agent string. Exclude compliant devices? Register one.
What it should look like:
Users: All users (break-glass accounts excluded)
Cloud apps: All cloud apps
Conditions: None
Grant: Require MFA (phishing-resistant if possible)
What we usually find:
Users: All users
Cloud apps: All cloud apps
Conditions: Exclude trusted locations, exclude compliant devices
Grant: Require MFA
↑ each of these exclusions is a way in
On every engagement where we've bypassed device controls, an unconditional MFA policy would have stopped us or at least made our lives significantly harder. You can fake device compliance. You can spoof Global Secure Access for trusted location. You can change a User Agent string in seconds. Getting past a phishing-resistant MFA challenge tied to the actual human? That's a different proposition entirely.
Block unknown platforms
Don't just write policies for the platforms you know about. Write one that blocks everything you don't.
Lots of tenants still have a gap for Linux. Microsoft added it as a selectable platform a while back, but if your policies predate that, you might not have it covered. Check.
And remember: even a comprehensive platform block is only as strong as the User Agent string, so it needs to work alongside compliance requirements, not instead of them.
Use the double-negative pattern for device filters
When you want to block non-compliant or unregistered devices, configure the policy to Exclude matched devices using a positive operator. Everything that doesn't positively match — including devices with null properties — stays in scope.
If you use positive operators in an Include configuration for blocking, unregistered devices walk right through. We've covered why above, but it bears repeating because we see this misconfiguration constantly.
Layer compliance on top of platform controls
Platform = self-reported, spoofable. Compliance = checked against the directory, harder to fake (though not impossible, as we showed with the bait and switch).
Use both together. But make sure your compliance policies actually check something meaningful. A policy that only verifies "device is enrolled" isn't really verifying much.
Watch the logs
Even with solid policies, keep an eye on sign-in logs for things that look off: a user who's always on Windows suddenly showing up as Linux, a burst of new device registrations from unexpected sources, compliance state flipping on recently-registered devices, or sign-ins from unregistered devices to anything sensitive.
Are your policies actually doing what you think?
Quick gut-check:
- Do you have an MFA policy with genuinely zero conditions on all users?
- Is there a catch-all block for unknown or unsupported platforms?
- Are your device filter rules using the double-negative pattern?
- Do your compliance policies check actual device posture, not just enrolment?
- Are admin accounts restricted to specific known device IDs?
- Is anyone looking at sign-in logs for platform anomalies?
- Is Device Code flow blocked for device registration and Authentication Method registration?
If any of those are a "no" or an "I'm not sure," your Entra ID Conditional Access Policies might not be doing what you think they're doing.
... Mandatory plug ...
When we run these assessments, we use our Entra ID authentication toolkit that lets us present arbitrary device configurations to Entra ID; spoofing platforms, registering devices, spoofing Microsoft App protection (MAM) and manipulating compliance state. All to prove the gaps your policies hold. If you want to pressure-test your Conditional Access setup, get in touch with us.

