Microsoft Entra ID is currently undergoing a significant transformation. By September 30, 2025, all organizations must migrate from legacy MFA and SSPR policies to the new unified Authentication Methods policy. However, this migration process has introduced a critical security concern that many administrators may not be aware of.
During the migration to the new Authentication Methods policy, SMS sign-in is enabled by default. This means users can now sign in using just their phone number and an SMS code - without needing to know their username or password.
This is then controlled by the Authentication method as defined in the Entra security:
If you then edit the SMS option you will see the option to "User for sign-in" is ticked as below:
If you do not want this feature then this tick needs to be removed from this option!
While this feature was designed to simplify authentication for frontline workers, it creates a significant security vulnerability for information workers and general enterprise users.
The Security Risk: Your Phone Number Is Your Password
Here's why SMS sign-in poses a serious security threat in enterprise environments:
1. Phone Numbers Are Public Information
Employee phone numbers are often discoverable through:
- Exchange Online Global Address Lists
- Company directories
- Social media profiles
- Public business listings
- Previous data breaches
2. SMS Notifications Aren't Private by Default
Most smartphones display SMS messages on the lock screen by default. This means:
- An attacker who knows someone's phone number can trigger an SMS login code
- The code appears on the locked phone screen
- No device access is required to view the message
- The attack can be executed remotely
3. The Attack Scenario
- Attacker discovers employee phone number (via Exchange, social media, etc.)
- Attacker goes to Office 365 sign-in page
- Attacker enters the victim's phone number instead of email address
- System sends SMS code to victim's phone
- Code appears on victim's lock screen (if notification privacy not configured)
- Attacker gains access to the victim's account
4. Beyond Personal Phones
The risk extends to any scenario where SMS codes might be intercepted:
- SIM swapping attacks
- Shared or corporate devices
- Phones left unattended on desks
When Did This Start?
The SMS sign-in default enablement began rolling out as part of Microsoft's Authentication Methods policy migration process, which organizations must complete by September 30, 2025. This migration was originally scheduled for 2024 but was extended to give organizations more time to prepare.
The issue specifically occurs because when migrating from legacy policies to the new Authentication Methods policy, the "Use for sign-in" option is enabled by default for SMS settings, automatically enabling SMS sign-in for users who have phone numbers registered for MFA.
Finding Available Users
To help identify which users in your organization have SMS sign-in available you can use this PowerShell script that queries Microsoft Entra ID and exports the results, remember to update the connections in bold!
Script : sms-mobile-enabled.ps1
# App Registration Connection
$tenantId = "<tenant-id>"
$clientId = "<application-id>"
$clientSecret = "<secret>"
# Connect using app registration
$secureSecret = ConvertTo-SecureString $clientSecret -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential($clientId, $secureSecret)
Connect-MgGraph -TenantId $tenantId -ClientSecretCredential $credential
Write-Host "Searching for users with SMS sign-in enabled..." -ForegroundColor Green
$results = @()
$allUsers = Get-MgUser -All -Property "id,displayName,userPrincipalName,userType" | Where-Object { $_.UserType -ne "Guest" }
$totalUsers = $allUsers.Count
$processedCount = 0
foreach ($user in $allUsers) {
$processedCount++
Write-Progress -Activity "Processing Users" -Status "Checking user $processedCount of $totalUsers" -PercentComplete (($processedCount / $totalUsers) * 100)
try {
$phoneAuth = Get-MgUserAuthenticationPhoneMethod -UserId $user.Id -ErrorAction SilentlyContinue
if ($phoneAuth) {
foreach ($phone in $phoneAuth) {
if ($phone.SmsSignInState -eq "ready" -or $phone.SmsSignInState -eq "enabled") {
$results += [PSCustomObject]@{
DisplayName = $user.DisplayName
UserPrincipalName = $user.UserPrincipalName
PhoneNumber = $phone.PhoneNumber
PhoneType = $phone.PhoneType
SmsSignInState = $phone.SmsSignInState
}
}
}
}
}
catch {
continue
}
}
# Clear progress bar
Write-Progress -Activity "Processing Users" -Completed
# Console output with count
Write-Host "`n========================================" -ForegroundColor Cyan
Write-Host "SMS SIGN-IN ENABLED USERS SUMMARY" -ForegroundColor Cyan
Write-Host "========================================" -ForegroundColor Cyan
Write-Host "Total users found with SMS sign-in enabled: $($results.Count)" -ForegroundColor Yellow
Write-Host "Total users processed: $totalUsers" -ForegroundColor Gray
Write-Host "`nUsers with SMS sign-in enabled:" -ForegroundColor Green
# Display results in console
$results | Format-Table -AutoSize
# Export to CSV
$csvPath = "SMS_Enabled_Users_$(Get-Date -Format 'yyyyMMdd_HHmmss').csv"
$results | Export-Csv -Path $csvPath -NoTypeInformation
Write-Host "`nResults exported to: $csvPath" -ForegroundColor Green
Write-Host "CSV file saved in current directory: $(Get-Location)" -ForegroundColor Gray
When executed it will scan though all the users (excluding guest and B2B as these accounts are not affect by this)
Interpreting the Results
When you run this script, you'll see output like this which will tell you all the user that are "Available" for SMS Login as below:
========================================
SMS SIGN-IN ENABLED USERS SUMMARY
========================================
Total users found with SMS sign-in enabled: 696
Total users processed: 18624
Users with SMS sign-in enabled:
DisplayName UserPrincipalName PhoneNumber PhoneType SmsSignInState
----------- ----------------- ----------- --------- --------------
John Smith duck.dogders@croucher.cloud +44123456789 mobile enabled
Sarah Johnson james.bond@croucher.cloud +44987654321 mobile enabled
Each user listed can potentially sign in using only their phone number and SMS code, bypassing traditional username/password authentication.
Finding Enabled Users
We now need to find all users that have this feature enabled, not ready, so for that we will use the CSV from earlier and look at all those users and look for the following attributes in bold as below:
Found 1 phone method(s):
Phone Number: +44 7384751119
Phone Type: mobile
SMS Sign-In State: 'configured'
SMS sign-in: Configured
We need to report on all users that have either of those attributes as that will mean they gone further than "being ready"
Script : locate-enabled-smslogins.ps1
# App Registration Connection
$tenantId = "<tenant_id>"
$clientId = "<application_id>"
$clientSecret = "<secret_key>"
# Connect using app registration
$secureSecret = ConvertTo-SecureString $clientSecret -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential($clientId, $secureSecret)
Connect-MgGraph -TenantId $tenantId -ClientSecretCredential $credential
# Find the latest CSV file in current directory
$latestCSV = Get-ChildItem -Path "." -Filter "SMS_Enabled_Users_*.csv" | Sort-Object LastWriteTime -Descending | Select-Object -First 1
if (-not $latestCSV) {
Write-Host "No SMS_Enabled_Users_*.csv file found in current directory!" -ForegroundColor Red
exit
}
Write-Host "Processing latest CSV file: $($latestCSV.Name)" -ForegroundColor Green
$users = Import-Csv $latestCSV.FullName
Write-Host "Found $($users.Count) users to check detailed SMS sign-in status..." -ForegroundColor Yellow
Write-Host ""
$detailedResults = @()
$count = 0
foreach ($user in $users) {
$count++
Write-Progress -Activity "Checking Detailed SMS Status" -Status "User $count of $($users.Count): $($user.DisplayName)" -PercentComplete (($count / $users.Count) * 100)
try {
$phoneAuth = Get-MgUserAuthenticationPhoneMethod -UserId $user.UserPrincipalName -ErrorAction SilentlyContinue
if ($phoneAuth) {
foreach ($phone in $phoneAuth) {
$detailedResults += [PSCustomObject]@{
DisplayName = $user.DisplayName
UserPrincipalName = $user.UserPrincipalName
PhoneNumber = $phone.PhoneNumber
PhoneType = $phone.PhoneType
OriginalSmsSignInState = $user.SmsSignInState
DetailedSmsSignInState = $phone.SmsSignInState
SMSSignInStatus = if ($phone.SmsSignInState -eq "ready") { "SMS SIGN-IN READY" }
elseif ($phone.SmsSignInState -eq "enabled") { "SMS SIGN-IN ENABLED" }
elseif ($phone.SmsSignInState -eq "notConfigured") { "Not Configured" }
else { $phone.SmsSignInState }
}
}
} else {
$detailedResults += [PSCustomObject]@{
DisplayName = $user.DisplayName
UserPrincipalName = $user.UserPrincipalName
PhoneNumber = $user.PhoneNumber
PhoneType = $user.PhoneType
OriginalSmsSignInState = $user.SmsSignInState
DetailedSmsSignInState = "No Phone Methods"
SMSSignInStatus = "Account not Enabled"
}
}
}
catch {
$detailedResults += [PSCustomObject]@{
DisplayName = $user.DisplayName
UserPrincipalName = $user.UserPrincipalName
PhoneNumber = $user.PhoneNumber
PhoneType = $user.PhoneType
OriginalSmsSignInState = $user.SmsSignInState
DetailedSmsSignInState = "Error"
SMSSignInStatus = "Account not Enabled"
}
}
}
Write-Progress -Activity "Checking Detailed SMS Status" -Completed
# Display results
Write-Host "`n========================================" -ForegroundColor Cyan
Write-Host "DETAILED SMS SIGN-IN STATUS REPORT" -ForegroundColor Cyan
Write-Host "========================================" -ForegroundColor Cyan
Write-Host "Total users analyzed: $($detailedResults.Count)" -ForegroundColor Yellow
# Group by status
$statusSummary = $detailedResults | Group-Object SMSSignInStatus
Write-Host "`nStatus Summary:" -ForegroundColor Green
foreach ($status in $statusSummary) {
Write-Host " $($status.Name): $($status.Count) users" -ForegroundColor White
}
Write-Host "`nDetailed Results:" -ForegroundColor Green
$detailedResults | Format-Table -AutoSize
# Export detailed results
$detailedCSVPath = "SMS_Detailed_Status_$(Get-Date -Format 'yyyyMMdd_HHmmss').csv"
$detailedResults | Export-Csv -Path $detailedCSVPath -NoTypeInformation
Write-Host "`nDetailed results exported to: $detailedCSVPath" -ForegroundColor Green
Write-Host "CSV file saved in current directory: $(Get-Location)" -ForegroundColor Gray
The results will show that we have 7 notSupported users - which is triggered on an alternative number as this type of number is indeed not supported.
This is the entry in the CSV file for the "notSupported" people
"James Bond","james.bond:croucher.cloud","+44 7285412234","alternateMobile","ready","notSupported","notSupported"
This would therefore suggest that we have no users at the moment with this enabled, so it can be disabled without creating to much noise.
Notification Privacy
Ensure users configure notification privacy on their devices:
- iPhone: Settings > Notifications > Show Previews > When Unlocked
- Android: Settings > Apps > Notifications > On Lock Screen > Hide sensitive content
Conclusion
SMS sign-in in enterprise environments represents a significant downgrade in security posture, essentially reducing authentication to "something you have" (a phone) without the traditional "something you know" (password) component.
The PowerShell script provided gives you the tools to quickly identify affected users in your environment. Use this information to make informed decisions about your authentication policies and ensure your organization maintains strong security practices.