Microsoft 365 Security Hardening Guide
Security hardening is designed to reduce security risk by reducing the potential attack surface.
Before beginning, I would recommend checking out Microsoft Secure Score and Microsoft 365 ATP Recommended Configuration Analyser (ORCA). These are two, free resources which will tailor Microsoft 365 security hardening to your tenant. You will get an overview of your organisation and the changes you can make which will make the biggest impact.
Secure Score and ORCA are fantastic resources but not needed. ORCA is mainly tailored towards ATP license but regardless, it will give you great insight. I will explain below how to use them both but skip if you do not wish to use them.
Secure Score can be found be found by logging into your tenant and browsing to: https://security.microsoft.com/securescore
How to install/run Microsoft 365 ATP Recommended Configuration Analyser (ORCA)
Open Powershell as Admin
Run install-module -name orca
Ensure Exchange Online Management is installed - run install-module -name ExchangeOnlineManagement
Connect-ExchangeOnline -UserPrincipalName [email protected] (change contoso to your domain)
Run ‘Get-OrcaReport
It will then take 2 mins or so and will generate and auto-open a .html with the results
As always, security is inconvenient to some degree however, most changes can be implemented with very little effort and without much impact. Think logically before each change, i.e will disabling automatic forwarding break anything etc, if so plan accordingly.
Admin Center
Check for inactive/stale accounts
Closing accounts can easily be forgotten with miscommunication. There are a few ways to check for inactive accounts. My suggestion would be to go to admin.microsoft.com > export users > check last sign-in time.
I would also suggest using the reports feature which can be found in admin.microsoft.com > reports > usage. You will be able to generate a report and view the last time actioned an email/edited a file within OneDrive which can help tie up loose ends.
Review privileged roles (Global admin/Billing admin etc)
Ensure you use the Role Assignment feature and individually check each role and the assignee. This can allow easy visibility over privileged roles and who has access. All users should only have the access they need to carry out their duties, including administrators.. This feature can be found here: admin.microsoft.com > Role Assignments
Check Office 365 groups and ensure the permissions are set correctly (Private vs Public) vs (Open vs Closed)
You can check this via the admin.microsoft.com panel or you can open Exchange and check. You’re looking out for the ‘settings’ option on the Microsoft 365 group > then check to see if it is private or not. This also applies to distribution lists but you will need to browse Exchange Online to make the change. The specific setting is: Choose whether owner approval is required to join the group. Quite often management groups are left open and anyone can join.
Modern Authentication
Modern Authentication is very important and should be used alongside MFA. Without Modern MFA enabled, legacy authentication protocols can bypass MFA. You can disable this via Conditional Access or via admin.microsoft.com > Org Settings > Modern Authentication. You will need to disable all basic authentication protocol. Note - if anyone is using legacy authentication, it will no longer work. You can use Azure Sign-in logs to check for legacy client-apps before disabling any protocols.
MFA
Multi-factor Authentication should be enabled across all accounts except a ‘break-the-glass’ account in some rare scenarios. Microsoft reports that MFA can prevent up to 99% of account breaches. It’s convenient, easy to use and super easy to setup. You can enable it in many areas, you can enable it per user on Azure MFA page or you can use Conditional Access to have more granular control.
Break-The-Glass Administrator Account
This account should be created but very rarely used - if ever! - Only for emergencies! It sounds a lot like a stale account and it kinda is however, it is a recommendation by Microsoft and it should have a different MFA method setup than the other Administrator accounts. This is more of a ‘good practice’ than a security recommendation. Microsoft has a good write-up here: Break Glass Account
Consider turning off ‘User Consent to apps’
This feature can be found within admin.microsoft.com > org settings > ‘User consent to apps’ and essentially allows an end-user to grant consent for apps to access organisational data.
User owned apps and services
Consider turning off allowing users to access the Office store. This will allow the users to access apps which are not curated or managed by Microsoft.
Idle session timeout
Consider turning on a session timeout after inactivity after a set period. This will force a sign-off of Office Web Apps. This feature can be found here: admin.microsoft.com > org settings > Security & privacy > Idle Session timeout (Preview)
Set passwords to never expire
National Cyber Security Centre recommends disabling enforced password expiry. It doesn’t really add any protection and in some cases, can allow for easier exploitation. You can read their recommendation here: NCSC Password Expiry
This feature can be found here: admin.microsoft.com > org settings > Security & privacy > Password expiration policyConsider enabling Self-service password reset
This will allow a user to change their own password providing they reach a pre-set criteria (2 MFA methods etc). If the user believes they may have been compromised, this will allow them to change their own password promptly. This setting can be found in Azure AD.
Consider disabling ‘Let users add new guests to the organisation’
This can allow any user to create guests within the tenant. This can easily allow an external user to have access to company files etc and can allow the exfiltration of data.
This feature can be found here: admin.microsoft.com > org settings > Security & privacy > Sharing
Security
Some extra security hardening can be completed depending on the license you have. I will add some of the more key points but this is mainly aimed at the lowest level license such as exchange online, essentials, basic etc… This is to ensure a good baseline is met.
Now, when it comes to threat policies, I would highly recommend running the ORCA Auditing tool via Powershell within your tenant.
Orca is primarily focused on Advanced Threat Protection(ATP) which is an additonal license however, you do not need ATP. It will give useful insights elsewhere. See the guide here: https://practical365.com/introducing-the-office-365-atp-recommended-configuration-analyzer-orca/
Anti-phishing - Spoof protection
There are many additional ways to help prevent malicious actors impersonating your domain such as SPF, DKIM and DMARC but I won’t cover it here. Spoof protection/Spoof Intelligence will allow you to have some control over impersonation of your domain. You can find this setting via https://security.microsoft.com/antiphishing > Spoof protection
You can also view who is currently spoofing your domain.
Anti-phishing - Turn on Safety tips & indicators
This can allow users a better insight into what may be suspicious. You can turn on ‘First contact’ which will give a recipient a little banner on an email the first time they received contact from a sender. ‘Unauthenticated senders’ and ‘via tag’ can help identify when an email received is from a spoofed domain. There’s not really a downside to these. You can find these settings here: https://security.microsoft.com/antiphishing > Edit actions
Anti-phishing - Change spoof emails from junk to quarantine
If you have your spoofing policy setup correctly, you should also ensure all emails which are likely to be impersonation should go into quarantine.
There will be a few listed here, all are Microsoft’s standard recommendations which can be found here: https://docs.microsoft.com/en-us/microsoft-365/security/office-365-security/recommended-settings-for-eop-and-office365?view=o365-worldwide#anti-spam-anti-malware-and-anti-phishing-protection-in-eop
Anti-spam inbound policy: https://security.microsoft.com/threatpolicy
Retain spam in quarantine for 30 days
This is Microsoft’s standard recommendation
Enable safety tips
Enable Zero-hour purge (ZAP)
Move spam emails to quarantine
Move high-confidence spam to quarantine
Move phishing emails to quarantine
Turn on Bulk email and spam action
Turn Bulk email threshold to 6
Remove whitelisting for domains and senders (at the very least remove internal domains!!! - This can allow domains impersonating yours to skip the filter)
Anti-spam inbound policy: https://security.microsoft.com/threatpolicy
Set external message limit to 500
Set internal message limit to 1000
Set daily message limit to 1000
Set ‘Over limit action’ to ensure if someone exceeds these limits, it will block them for that day or until an admin reviews
Setup ‘Notify users and groups’ so an admin is notified when a user has exceeded these limits
Set Auto forwarding to ‘Automatic - System-controlled’ or ‘Disabled’ (This will stop all external forwarding within your organisation so ensure none is setup or needed before)
Enable End-user spam notifications: https://security.microsoft.com/quarantinePolicies
Set to 3 days
Connection filter policy: https://security.microsoft.com/threatpolicy
Remove any IP’s allowed if possible
Anti-Malware Policy: https://security.microsoft.com/antimalwarev2
Enable the common attachments filter
Enable Zero-purge for malware
Ensure the quarantine policy is set to AdminOnly to ensure users cannot release malware
Turn on admin notifications for internal and external senders to ensure you have a log
DKIM: https://security.microsoft.com/dkimv2
DKIM should be enabled for all your domains within your Office 365. DKIM is email authentication and allows the recipient to check that an emailed they received was authorised by your domain via a digital signature. There is a little setup required and will need some further time spent but it is a must!
Turn on ‘User submissions’: https://security.microsoft.com/userSubmissionsReportMessage
This will allow a ‘Microsoft Outlook Report Button’ to appear within their Outlook and will allow users to report emails to admins.
Ensure auditing is turned on: https://security.microsoft.com/auditlogsearch
I cannot stress this enough! This should be one of your highest priorities. This will help audit actions or to look for potential malicious actions.
All new O365 tenants (after 2019) should have this turned on by default but older tenants will not. Check regardless!
Compliance
Turn on the default alerts and add the correct contact to ensure they’re notified: https://compliance.microsoft.com/alertpolicies
This will include many many alerts and some may not be as relevant as others. You can turn them all on, there’s currently 28 default alerts and I would expect 15-20 will be relevant to all tenants.
Create retention policy for key/critical data - https://compliance.microsoft.com/informationgovernance?viewid=retention
This will ensure the key data you have is retained and not accidentally or maliciously deleted. This can be applied to emails, Microsoft Teams and SharePoint
Data Loss Prevention (DLP)
This is a licensed feature however, you can create labels on any default license which can help around this issue alongside retention policies. It’s definitely not the same but it’s something if nothing else.
Azure Active Directory
Turn on MFA for all users
This can be completed manually or via Conditional Access (License required for Conditional Access)
Enable Password reset: https://aad.portal.azure.com/#blade/Microsoft_AAD_IAM/PasswordResetMenuBlade/Properties
This will allow a self-service password reset. Users will require to use 1 or 2 methods (dependent on the setting) to be able to reset their password.
Turn on notify all admins when other admins reset their password: https://aad.portal.azure.com/#blade/Microsoft_AAD_IAM/PasswordResetMenuBlade/Notifications
This can help indicate if an administrative account is compromised.
Turn on notify users on password resets: https://aad.portal.azure.com/#blade/Microsoft_AAD_IAM/PasswordResetMenuBlade/Notifications
This will alert the users so that they have an indication if their password was reset.
Turn off ‘Users can register applications’: https://aad.portal.azure.com/#blade/Microsoft_AAD_IAM/UsersManagementMenuBlade/UserSettings
Having this feature on can allow 3rd party apps to potentially exfiltrate data
Turn on ‘Restrict Access to Azure AD Administration portal’: https://aad.portal.azure.com/#blade/Microsoft_AAD_IAM/UsersManagementMenuBlade/UserSettings
It’s not relevant for standard users.
Turn off Guest users or set to the strictest option 'Guest user access is restricted to properties and memberships of their own directory objects (most restrictive)’: https://aad.portal.azure.com/#blade/Microsoft_AAD_IAM/AllowlistPolicyBlade
Without a complete Guest user configuration, they can access data they have not been given access to which can allow to data leaks/breaches etc
Turn off Guest Invites and or set to admin roles only: https://aad.portal.azure.com/#blade/Microsoft_AAD_IAM/AllowlistPolicyBlade
Guest users have the potential to exfiltrate data. If a user invited a malicious actor posing as a guest, they could potentially exfiltrate data.
Turn off Guest self-service sign up via user flows: https://aad.portal.azure.com/#blade/Microsoft_AAD_IAM/AllowlistPolicyBlade
This can potentially circumnavigate Guest user setups which should ideally be completed by an Admin
Turn off ‘Users can create security groups in Azure portals, API or PowerShell’: https://aad.portal.azure.com/#blade/Microsoft_AAD_IAM/GroupsManagementMenuBlade/General
Users do not need this as standard.
Turn off ‘Users can create Microsoft 365 groups in Azure portals, API or PowerShell’: https://aad.portal.azure.com/#blade/Microsoft_AAD_IAM/GroupsManagementMenuBlade/General
This can allow users to create 365 groups which can create a messy environments. They could potentially misconfigure permissions
Ensure ‘Users can request admin consent to apps’ is set to No: https://aad.portal.azure.com/#blade/Microsoft_AAD_IAM/StartboardApplicationsMenuBlade/UserSettings/menuId/
Users can grant consent to 3rd party apps which can exfiltrate data or act on their behalf.
Turn on ‘Do not allow user consent’ within Enterprise apps: https://aad.portal.azure.com/#blade/Microsoft_AAD_IAM/ConsentPoliciesMenuBlade/UserSettings
Users can grant consent to 3rd party apps which can exfiltrate data or act on their behalf.
Turn on ‘Do not allow group owner consent’ within Enterprise Apps: https://aad.portal.azure.com/#blade/Microsoft_AAD_IAM/ConsentPoliciesMenuBlade/UserSettings
Users can grant consent to 3rd party apps which can exfiltrate data or act on their behalf.
Set ‘Users may join devices to Azure AD’ or ensure MFA must be used to register devices: https://aad.portal.azure.com/#blade/Microsoft_AAD_Devices/DevicesMenuBlade/DeviceSettings/menuId/
This could allow a potential compromised account to join any device to Azure AD where further access/data may be gained.
Setup Company Branding: https://aad.portal.azure.com/#blade/Microsoft_AAD_IAM/ActiveDirectoryMenuBlade/LoginTenantBranding
This can potentially allow users to avoid pages which do not have their browsing which can prevent phishing attacks from being successful however, user training should be provided to ensure they still check URLs etc as Company Branding could be spoofed.
Exchange
Mailflow rules
Check to ensure relevant rules remain
Turn off ‘Allow automatic forwarding’ within Remote Domains > Default > Edit reply types
This will disable all external email forwarding. Check to ensure external emails are not being used before making this change.
Turn on all Alert Policies listed here: https://admin.exchange.microsoft.com/#/alerts/recentalertsmailflowdetails
Set notifications to admins.
Ensure connectors are relevant
SharePoint and OneDrive
Set external sharing to at least ‘New and Existing Guests’ for SharePoint and Onedrive > browse to Admin center > Sharepoint > Sharing
External sharing should not be set to anyone as this will allow anonymous access with no accountability.
Turn on ‘Guests must sign in using the same account to which sharing invitations are sent’ > browse to Admin center > Sharepoint > Sharing > More External Sharing Settings
Guests should be limited as much as possible if used within your environment
Turn off ‘Allow Guests to share items they don’t own’ > browse to Admin center > Sharepoint > Sharing > More External Sharing Settings
Guests should be limited as much as possible if used within your environment, they should not be able to share internal files.
Turn on ‘Guest access to a site or OneDrive will expire automatically after at most 60 days’. > browse to Admin center > Sharepoint > Sharing > More External Sharing Settings
Users typically forget to set an expiry. This can stop permanent access to folders/files.
Turn on ‘People who use a verification code must reauthenticate after at most 30 days’ > browse to Admin center > Sharepoint > Sharing > More External Sharing Settings
This will enforce some regular MFA
Change the default sharing to be ‘Specific people’ or Only people in your organisation’ but NOT ‘anyone with the link’ - this should be disabled by setting the first recommendedhardening ‘External sharing’ > browse to Admin center > Sharepoint > Sharing
Anyone with link is very bad practice and can allow sharing with malicious actors and/or no accountability and limited auditing.
Change default permission to ‘View’ > browse to Admin center > Sharepoint > Sharing
This will involve communicating with staff so that they’re aware they will change however, this will set the least privilege available rather than the most
Enable expiration and permissions for anyone links browse to Admin center > Sharepoint > Sharing
Expiration after at most 10 days
Permissions set to View
Anyone links should be disabled via the first change you make but I would still recommend setting these.
Set ‘Idle session sign-out’ to 1 hour > browse to Admin center > Sharepoint > Access Control > Idle Session sign-out
Give users notice (preference)
No downside to this and can ensure users do not accidentally leave themselves signed in at all times.
Lock down Access to IP range if possible > browse to Admin center > Sharepoint > Access Control > Network Location
Not likely… this is not an easy change and is only possible if a company needs access only from their office(s) etc.
Block Access from apps that don’t use modern authentication > browse to Admin center > Sharepoint > Access Control > Apps that don’t use modern authentication
Legacy access should be blocked already but I still recommend changing this setting
Disable ‘Let users create sites’ > browse to Admin center > Sharepoint > Settings > Site creation
This can create a messy enviroment as users can create as many sites as they need and many O365 groups however, with training, this can be left enabled.
Turn on ‘Only allow syncing on computers joined to specific domains’ (This is a nice to have but most likely not possible for most orgs)
Quite a hard one to implement but if possible, can potentially prevent exfiltration of data.
Teams
Configure which users are allowed to present in Teams meetings: Organizers, but users can override > Teams Admin Center > Meetings > Meeting Policies > Select your meeting policy or default > Participants & Guests section
This will enforce a hierarchy and ensure sessions cannot be hijacked.
Only invited users should be automatically admitted to Teams meetings set to "Automatically admit people" to Invited users only > Teams Admin Center > Meetings > Meeting Policies > Select your meeting policy or default > Participants & Guests section
Allowing anyone to be automatically admitted can potentially allow them to hear sensitive data. If a malicious actor gained the meeting link, they could potentially listen in.
Restrict anonymous users from starting Teams meetings set "Let anonymous people start a meeting" to Off > Teams Admin Center > Meetings > Meeting Policies > Select your meeting policy or default > Participants & Guests section
Anonymous users should not be incharge of any meetings within your organisation.
Limit external participants from having control in a Teams meeting set "Allow an external participant to give or request control" to Off > Teams Admin Center > Meetings > Meeting Policies > Select your meeting policy or default > Content Sharing section
External participants should not be able to gain access/control of your a device within your organisation.
Turn off ‘Guest Access in Teams’ if not needed: https://admin.teams.microsoft.com/company-wide-settings/guest-configuration
Guest Access should be turned off if not needed. They can have access to company data etc by default.
Limit communication to external domains if possible: https://admin.teams.microsoft.com/company-wide-settings/external-communications
External communication can allow malicious actors to Teams users or to exfiltrate data/information.