Back to blog
| 10 min read

M365 Security Baselines: What Your Tenant Is Missing

Your M365 tenant came with defaults optimized for convenience, not security. Legacy authentication is open, conditional access is nonexistent, audit logging is minimal, and sharing is unrestricted. Here is the practical checklist for locking it down before an attacker does it for you.

M365 Security Conditional Access PowerShell

The default M365 tenant is not secure

When you provision a new Microsoft 365 tenant, it works out of the box. Users can sign in, send email, share files, and join Teams meetings. That functional baseline is exactly what makes it dangerous — everything is permissive by default, and Microsoft leaves the hardening to you.

Out of the box, here is what your tenant allows: legacy authentication protocols (IMAP, POP3, SMTP AUTH) that bypass MFA entirely. No conditional access policies, meaning any device from any location can authenticate. Minimal unified audit logging with short retention. Anonymous sharing links in SharePoint and OneDrive. Unrestricted guest access in Teams. No anti-phishing policies beyond basic EOP defaults.

This is not theoretical risk. Business email compromise (BEC) attacks are the single most costly cybercrime category, accounting for over $2.9 billion in reported losses in 2023 alone according to the FBI IC3 report. The attack pattern is almost always the same: an attacker phishes credentials, logs in via a legacy auth protocol that has no MFA challenge, sets up a mailbox forwarding rule to exfiltrate data, and operates undetected because audit logging was not configured to catch it.

Consent phishing is the other major vector. An attacker sends a legitimate-looking OAuth consent prompt. The user clicks "Accept," and now a malicious app has read access to their mailbox and files — no credentials stolen, no MFA bypassed, just a user clicking a button that Microsoft's defaults allowed.

"It works" is not the same as "it's secure." Let's fix the gaps.

Identity & Access: The big three policies

Conditional Access is the control plane for M365 identity security. Without it, you are relying on users to make good decisions. These three policies should be deployed in every tenant, regardless of size.

Policy 1: Require MFA for all users

Not just admins. Everyone. Microsoft's own data shows that MFA blocks 99.9% of automated attacks. The most common objection is "our users will complain." They will complain more when their mailbox is compromised and the CEO's wire transfer instructions turn out to be from an attacker in Lagos.

Use Security Defaults as a minimum if you do not have P1 licensing, but conditional access policies give you far more control. Exclude a break-glass account (and monitor it heavily).

Key detail: Security Defaults and Conditional Access are mutually exclusive. If you enable CA policies, disable Security Defaults first or they will conflict.

Policy 2: Block legacy authentication protocols

Legacy auth protocols — IMAP, POP3, SMTP AUTH, Exchange ActiveSync with basic auth, and Exchange Web Services with basic auth — do not support MFA. An attacker with a valid username and password can authenticate via IMAP even if the user has MFA enabled on their account. This is not a bug; it is how the protocols work.

Create a conditional access policy that targets all users, all cloud apps, and blocks the "Other clients" condition. This catches all legacy auth protocols. Test with report-only mode first — you may have a multifunction printer or an old app still using basic SMTP auth.

Policy 3: Require compliant or hybrid-joined devices

If you have Intune or hybrid Azure AD join deployed, add a policy that requires devices accessing Office 365 apps to be compliant or domain-joined. This prevents access from unmanaged personal devices, kiosk machines, and attacker-controlled endpoints. For BYOD scenarios, use app protection policies as an alternative grant.

Audit your current state with PowerShell

Before creating new policies, audit what exists. Many tenants have stale or conflicting conditional access policies from previous admins.

# Connect to Microsoft Graph
Connect-MgGraph -Scopes "Policy.Read.All"

# List all Conditional Access policies with their state
Get-MgIdentityConditionalAccessPolicy | Select-Object `
  DisplayName, State, CreatedDateTime, ModifiedDateTime |
  Format-Table -AutoSize

# Check for policies in report-only mode (common leftover)
Get-MgIdentityConditionalAccessPolicy |
  Where-Object { $_.State -eq "enabledForReportingButNotEnforced" } |
  Select-Object DisplayName

Check MFA registration status across users

Before enforcing MFA, identify who has not registered yet. Rolling out MFA enforcement without a registration campaign leads to locked-out users and a flooded helpdesk.

# Get MFA registration details for all users
Connect-MgGraph -Scopes "UserAuthenticationMethod.Read.All","User.Read.All"

# Pull authentication method registration status
$Users = Get-MgUser -All -Property DisplayName, UserPrincipalName, Id
$Report = foreach ($User in $Users) {
  $Methods = Get-MgUserAuthenticationMethod -UserId $User.Id
  [PSCustomObject]@{
    DisplayName       = $User.DisplayName
    UPN               = $User.UserPrincipalName
    MethodCount       = $Methods.Count
    HasMFA            = ($Methods.Count -gt 1)  # Password = 1, MFA = 2+
  }
}

# Show users without MFA registered
$Report | Where-Object { -not $_.HasMFA } |
  Sort-Object DisplayName |
  Format-Table -AutoSize

Email security essentials

Email is the primary attack surface for most organizations. M365 provides layered defenses, but most of them require manual configuration.

SPF, DKIM, and DMARC records

These three DNS records work together to prevent domain spoofing. SPF declares which servers can send email for your domain. DKIM cryptographically signs outbound messages. DMARC tells receiving servers what to do when SPF or DKIM fails. Without all three, anyone can send email that looks like it came from your domain.

# SPF record — add as TXT record on your domain
v=spf1 include:spf.protection.outlook.com -all

# DKIM — enable via Exchange Admin Center or PowerShell
# Two CNAME records are required per domain:
selector1._domainkey.contoso.com → selector1-contoso-com._domainkey.contoso.onmicrosoft.com
selector2._domainkey.contoso.com → selector2-contoso-com._domainkey.contoso.onmicrosoft.com

# DMARC record — start with monitoring, then enforce
# Phase 1 (monitor):
v=DMARC1; p=none; rua=mailto:dmarc-reports@contoso.com; pct=100

# Phase 2 (quarantine after reviewing reports):
v=DMARC1; p=quarantine; rua=mailto:dmarc-reports@contoso.com; pct=100

# Phase 3 (reject — full enforcement):
v=DMARC1; p=reject; rua=mailto:dmarc-reports@contoso.com; pct=100

Key detail: Do not jump straight to p=reject. Start with p=none and monitor the aggregate reports for 2-4 weeks. You will almost certainly discover legitimate services sending email from your domain that you forgot about (marketing tools, CRM systems, ticketing platforms).

Anti-phishing policies in Defender for Office 365

If you have Microsoft Defender for Office 365 (Plan 1 or 2), configure these anti-phishing settings. The defaults are intentionally conservative — Microsoft errs on the side of not blocking legitimate mail, which means phishing gets through.

Enable user impersonation protection for your executives and finance team
Enable domain impersonation protection for your primary domains
Set mailbox intelligence to quarantine (not just add a safety tip)
Enable first-contact safety tips so users are warned when they receive mail from someone for the first time

Safe Links and Safe Attachments

Safe Links rewrites URLs in email messages and checks them at click time — not just at delivery time. An attacker can send a clean URL and weaponize it after delivery. Safe Attachments detonates attachments in a sandbox before delivering them. Enable both for all users, and enable Safe Attachments for SharePoint, OneDrive, and Teams as well.

Mailbox forwarding rules: The #1 BEC persistence mechanism

After compromising an account, the first thing an attacker does is create a forwarding rule. This lets them silently receive copies of all incoming email even after you reset the password and enable MFA. Check for these regularly.

# Connect to Exchange Online
Connect-ExchangeOnline

# Find mailboxes with external forwarding (SMTP forwarding)
Get-Mailbox -ResultSize Unlimited |
  Where-Object { $_.ForwardingSmtpAddress -ne $null } |
  Select-Object DisplayName, UserPrincipalName, ForwardingSmtpAddress,
    DeliverToMailboxAndForward |
  Format-Table -AutoSize

# Find inbox rules that forward or redirect externally
$Mailboxes = Get-Mailbox -ResultSize Unlimited
foreach ($mbx in $Mailboxes) {
  $Rules = Get-InboxRule -Mailbox $mbx.UserPrincipalName -ErrorAction SilentlyContinue |
    Where-Object { $_.ForwardTo -or $_.ForwardAsAttachmentTo -or $_.RedirectTo }
  if ($Rules) {
    foreach ($rule in $Rules) {
      [PSCustomObject]@{
        Mailbox     = $mbx.UserPrincipalName
        RuleName    = $rule.Name
        ForwardTo   = $rule.ForwardTo -join ";"
        RedirectTo  = $rule.RedirectTo -join ";"
        Enabled     = $rule.Enabled
      }
    }
  }
} | Format-Table -AutoSize

Pro tip: Set a transport rule to block automatic external forwarding tenant-wide. Users rarely have a legitimate reason to forward all their email externally, and this single rule shuts down one of the most common BEC persistence techniques.

Audit logging: What to turn on

Unified audit logging is enabled by default in M365, but "enabled" does not mean "useful." Many critical events are not captured at the default level, retention is only 90 days (180 for E5), and mailbox-level auditing has its own separate configuration.

Enable mailbox audit logging for all mailboxes

Since January 2019, Microsoft enables mailbox auditing by default for new mailboxes. But mailboxes created before that date, or mailboxes where auditing was manually disabled, may not have it. Verify and enforce across the tenant.

# Check which mailboxes do NOT have audit logging enabled
Get-Mailbox -ResultSize Unlimited |
  Where-Object { $_.AuditEnabled -eq $false } |
  Select-Object DisplayName, UserPrincipalName, AuditEnabled |
  Format-Table -AutoSize

# Enable auditing on all mailboxes that have it disabled
Get-Mailbox -ResultSize Unlimited |
  Where-Object { $_.AuditEnabled -eq $false } |
  ForEach-Object {
    Set-Mailbox -Identity $_.UserPrincipalName -AuditEnabled $true
    Write-Host "Enabled audit logging for $($_.UserPrincipalName)"
  }

# Verify the default audit actions are comprehensive
Get-Mailbox -Identity "admin@contoso.com" |
  Select-Object AuditAdmin, AuditDelegate, AuditOwner

Configure alert policies for critical events

M365 ships with some default alert policies, but they are limited. Create custom alerts for the events that matter most in a breach scenario.

Impossible travel — a user signs in from New York and then from Singapore 20 minutes later
Mass file downloads — a user downloads hundreds of files from SharePoint in a short window
Admin role changes — any modification to Global Admin, Exchange Admin, or SharePoint Admin roles
Mail forwarding rules created — especially rules forwarding to external domains
OAuth app consent — a user consents to a new third-party application

Extend audit log retention

The default 90-day retention is not enough for compliance or incident response. Most security frameworks (NIST, CIS, SOC 2) require at least one year. If you have E5 or E5 Compliance add-on licensing, you can configure up to 10 years of retention.

# Connect to Security & Compliance PowerShell
Connect-IPPSSession

# Create a 1-year retention policy for all audit records
New-UnifiedAuditLogRetentionPolicy `
  -Name "1-Year Audit Retention" `
  -Description "Retain all audit logs for 365 days" `
  -RetentionDuration TwelveMonths `
  -Priority 100

# Verify the policy was created
Get-UnifiedAuditLogRetentionPolicy | Format-Table Name, RetentionDuration, Priority

Budget alternative: If you do not have E5 licensing, export audit logs to an Azure Log Analytics workspace or a SIEM on a scheduled basis. A simple PowerShell scheduled task pulling Search-UnifiedAuditLog daily and writing to CSV is better than losing the data entirely.

SharePoint and OneDrive sharing defaults

The default sharing settings in SharePoint Online and OneDrive for Business are designed for maximum collaboration. That means "Anyone with the link" sharing is enabled, anonymous access is allowed, and there are no restrictions on external sharing. For most organizations, this is far too permissive.

Tighten sharing settings

At minimum, disable anonymous sharing links and restrict external sharing to authenticated users from specific domains. Here is how to check and configure the settings via PowerShell.

# Connect to SharePoint Online
Connect-SPOService -Url "https://contoso-admin.sharepoint.com"

# Check current tenant-level sharing settings
Get-SPOTenant | Select-Object `
  SharingCapability,
  DefaultSharingLinkType,
  FileAnonymousLinkType,
  FolderAnonymousLinkType,
  RequireAcceptingAccountMatchInvitedAccount

# Restrict to authenticated external users only (no anonymous links)
Set-SPOTenant -SharingCapability ExternalUserSharingOnly

# Set default link type to "Specific people" instead of "Anyone"
Set-SPOTenant -DefaultSharingLinkType Direct

# Require external users to accept sharing invitation with same account
Set-SPOTenant -RequireAcceptingAccountMatchInvitedAccount $true

# Optional: Restrict sharing to specific domains
Set-SPOTenant -SharingDomainRestrictionMode AllowList `
  -SharingAllowedDomainList "partnercorp.com vendorco.com"

Enable DLP policies for sensitive files

Data Loss Prevention policies can detect and block sharing of files containing sensitive information like credit card numbers, Social Security numbers, or health records. Start with the built-in sensitive information types and add custom patterns for your industry.

Create a DLP policy targeting SharePoint Online and OneDrive for Business
Use built-in templates for PII, financial data, and HIPAA (if applicable)
Start in test mode with notifications to see what gets flagged before enforcing
Block external sharing of files that match DLP rules

Teams security: The overlooked surface

Teams is the most underestimated attack surface in M365. It combines chat, file sharing, meetings, and third-party app integrations into a single platform that most security teams treat as "just a chat app." The default settings are permissive, and most organizations never touch them.

Guest access policies

By default, anyone in your organization can invite external guests to Teams. Those guests then get access to the team's channels, files, and chat history. Tighten this down.

Restrict who can invite guests — limit to specific roles or a security group of team owners
Set guest access to expire after a defined period (90 days is a common default)
Disable guest access to specific teams containing sensitive data
Review existing guests quarterly — stale guest accounts are a real risk

Meeting policies

Default meeting settings allow anonymous users to join meetings, bypass the lobby, and present content. For internal meetings this might be acceptable, but for an organization handling sensitive information, lock it down.

Enable lobby for external participants and anonymous users
Restrict who can present to organizers and co-organizers by default
Control recording permissions — decide if recordings are auto-saved to OneDrive and who can access them
Disable anonymous join for meetings if your organization does not need it

Third-party app restrictions

Teams supports third-party apps that can access messages, files, and user data. By default, users can install any app from the Teams store. This is the consent phishing vector applied to Teams instead of email.

Block all third-party apps by default, then allowlist the ones you have vetted
Disable sideloading of custom apps unless you have a developer team that needs it
Review app permissions quarterly — check what data each app can access

Quick-win checklist: 10 things to do today

In priority order. You can get through all ten in about an hour. Each one meaningfully reduces your attack surface.

1. Enable Conditional Access: Block legacy authentication

Create a CA policy that blocks "Other clients" for all users. This single policy closes the biggest authentication gap in your tenant. Deploy in report-only first, verify no legitimate services break, then enforce.

2. Require MFA for all users via Conditional Access

If you already have Security Defaults, this is done. If not, create a CA policy requiring MFA for all cloud apps. Exclude one break-glass account and set up alerting on that account's sign-ins.

3. Block external mail forwarding tenant-wide

Create a mail flow rule in Exchange Admin Center that blocks automatic external forwarding. This prevents the most common BEC persistence technique. Takes two minutes and stops a real attack pattern.

4. Check for existing external forwarding rules

Run the forwarding audit script from the email section above. If you find forwarding rules you did not create, treat it as a potential compromise. Investigate immediately.

5. Publish SPF, DKIM, and DMARC records

If you do not have all three, add them now. SPF takes one DNS record. DKIM takes two CNAMEs and a toggle. DMARC takes one TXT record in monitoring mode. You can deploy all three in under 15 minutes.

6. Disable "Anyone" sharing links in SharePoint/OneDrive

Change the tenant sharing level to "Existing external users" or "New and existing external users" — anything but "Anyone." Set the default link type to "Specific people."

7. Enable mailbox audit logging for all mailboxes

Run the audit check script from above. Enable auditing on any mailboxes that have it disabled. This takes one command and gives you visibility into mailbox access that you cannot get any other way.

8. Restrict third-party app consent in Azure AD

In Entra ID, go to Enterprise applications and set "Users can consent to apps accessing company data on their behalf" to No. Require admin approval for app consent. This stops consent phishing attacks.

9. Enable Safe Links and Safe Attachments

If you have Defender for Office 365, create policies that cover all users. Enable URL detonation, real-time URL scanning on click, and Safe Attachments for SharePoint, OneDrive, and Teams.

10. Review admin role assignments

Check who has Global Admin. You should have no more than 2-4 Global Admins, plus a break-glass account. Everyone else should have the minimum role required. Use PIM (Privileged Identity Management) for just-in-time activation if you have P2 licensing.

Want the full hardening kit?

The M365 Tenant Hardening Kit takes everything in this post and turns it into actionable scripts, templates, and runbooks. Stop copying commands from blog posts — deploy a tested, repeatable hardening process across every tenant you manage.

  • 80+ item security checklist covering identity, email, sharing, Teams, and compliance
  • Conditional Access policy templates ready to import
  • Audit monitoring script with automated alerting and reporting
  • Tenant hardening report script — run it to get a scored baseline assessment
  • 4 incident response playbooks for BEC, consent phishing, data exfiltration, and account compromise
View M365 Hardening Kit $79 one-time purchase