Protect your tenant against Hidden Inbox Rules in Exchange Online using PowerShell

I – Introduction

Information security is a major issue for all companies. With cyberattacks constantly on the rise, it’s essential to understand and effectively manage potential vulnerabilities in your systems. One topic that is often overlooked is that of hidden rules in Microsoft Exchange 365.

II – Hidden Rules

Rules in Microsoft Exchange 365 are powerful tools that can automate a multitude of tasks. However, there are rules that can be hidden and therefore not appear in the user’s list of rules. These hidden rules can be used for malicious purposes, such as automatically forwarding e-mails to third parties, which can lead to information leaks.

III – Overview of the Attack process :

The attack consists of the following 5 steps:

IV – Detection & Remediation :

Detecting hidden inbox rules can be tricky. Depending on the rule and how it is created, the event will not appear in the Office 365 Unified Audit Log. Administrators may be able to detect transfer rules if they’ve set up the alert, but after testing, some said it only worked for rules with the “Transfer” action. It didn’t seem to work for rules with the “DeleteMessage”, “MoveToFolder”, “RedirectTo”, or “ForwardAsAttachmentTo” action.

Today I’d like to show you an effective way of detecting and deleting hidden rules using PowerShell.

here is an exemple of hidden rule, as you can see Hidden rules have no name :

The program I am presenting to you today allows you to :

  1. – Display whether there are accounts with hidden rules for all exchange Online mailboxes
  2. – Remove hidden rules for all exchange Online mailboxes
  3. – Briefly display mailboxes with rules (any type of rule)
  4. – Show details of mailboxes with rules (all rule types)

this is the main program window :

When you select option 1 , program will start scanning your Exchange Online mailboxes for hidden rules, the display mailboxes with hidden rules (In my case I dont have hidden to display sorry)

this is the result after choosing option 1 :

Option 2 will proceed directly with deleting hidden rules , so you can see I have 0 hidden rules deleted

By choosing option Number 3, the program display mailboxes name with rules (All type of rules) :

By choosing option 4, the program display some details about mailboxes with rules (All type of rules) :

by using this option (4) you will be able to detect even external forward rules , as you can see on this example :

and now the best part of this article, quiu is the source code :

Set-ExecutionPolicy RemoteSigned -Force

# Import Exchange Online module
Import-Module ExchangeOnlineManagement

# connect to Exchange Online
Connect-ExchangeOnline 


# ===================================================== Remove-HiddenRules ==========================================================

Function Show-HiddenRules 
{
  $mailboxes = Get-EXOMailbox
  $Hrules = 0
  Foreach ($mailbox in $mailboxes)
  {
    $hiddenrules = Get-InboxRule -Mailbox $mailbox -IncludeHidden | Where-Object {$_.Name -notin (Get-InboxRule -Mailbox $mailbox).name -and ($_.Name -ne "Junk E-Mail Rule")}
    If ($hiddenrules) 
    {
        $Hrules ++ 
        Foreach ($rule in $hiddenRules) 
        { 
            
            Write-Host "This Mailbox -- $($mailbox.UserPrincipalName) contain $($hiddenRules.count) hidden rules" -ForegroundColor Red
            $rule | Select-object Name, Description, Enabled, MarkAsRead, DeleteMessage, MoveToFolder,  From , RedirectTo, ForwardTo | fl
        }
    }
  }
  if($Hrules -eq 0)
  {
    Write-Host "No hidden Rules in Exchange Online Tenant............" -ForegroundColor Green
    Write-Host
    Write-Host
  }
}

# ===================================================== Remove-HiddenRules ==========================================================

Function Remove-HiddenRules 
{
    $mailboxes = Get-EXOMailbox
    $Hrules = 0
    # browse mailboxes
    Foreach ($mailbox in $mailboxes)
    {
        $hiddenrules = Get-InboxRule -Mailbox $mailbox -IncludeHidden | Where-Object {$_.Name -notin (Get-InboxRule -Mailbox $mailbox).name -and ($_.Name -ne "Junk E-Mail Rule")}
        If ($hiddenrules) 
        {
            Foreach ($rule in $hiddenRules) 
            {
                $Hrules++
                Write-Host "Removing rule -- $($rule.Name) -- from : $($mailbox.UserPrincipalName)" -ForegroundColor Green
                Remove-InboxRule -Identity $rule.Identity
            }
        }
    }
    
    Write-Host "Total hidden Rules that was deleted from your Tenant : $($Hrules)............" -ForegroundColor Green
    Write-Host
    Write-Host
}

# ===================================================== Show-AllRulesBrief ==========================================================

Function Show-AllRulesBrief 
{
    $mailboxes = Get-EXOMailbox
    $Trules = 0

    # browse mailboxes
    foreach ($mailbox in $mailboxes) 
    {
        # Retrieve mail rules for each mailbox
        $rules = Get-InboxRule -Mailbox $mailbox.Identity

        if($rules)
        {
            $Trules ++
            Write-Host "User Mailbox : $($mailbox.UserPrincipalName)  with $($rules.count) rules find : " -ForegroundColor Yellow
            
        }
    }

    if($Trules -eq 0)
    {
        Write-Host "Your dont have Any Rule In your Exchange Online Tenant" -ForegroundColor Green
        Write-Host
        Write-Host
    }
    Write-Host
    Write-Host
}


# ===================================================== Show-DetailedRules ==========================================================

Function Show-DetailedRules 
{
    $mailboxes = Get-EXOMailbox
    $Trules = 0

    # browse mailboxes
    foreach ($mailbox in $mailboxes) 
    {
        # Retrieve mail rules for each mailbox
        $rules = Get-InboxRule -Mailbox $mailbox.Identity

        if($rules)
        {
            $Trules ++

            Write-Host "Boîte aux lettres avec $($rules.count) règle trouvée : $($mailbox.UserPrincipalName)" -ForegroundColor Yellow
            $rules | Select-object Name, Description, Enabled, From , RedirectTo, ForwardTo | fl
            
        }
    }

    if($Trules -eq 0)
    {
        Write-Host "Your dont have Any Rule In your Exchange Online Tenant" -ForegroundColor Green
        Write-Host
        Write-Host
    }
    Write-Host
    Write-Host
}





$menu = @"

*****************************************************************************
                        EO Hidden Rules Remover
*****************************************************************************


    1) Show Hidden rules for all Users

    2) Remove Hidden rules for all Users

    3) Show All Users rules Brief

    4) Show All Users rules Detailed

    x) exit


*****************************************************************************


"@

do
{
    cmd /c color 71
    Write-Host $menu -ForegroundColor Green
    $Selection = Read-Host("Enter your choice ")
    clear-host
    Switch($Selection)
    {
        1 { cls
            Write-Host
            Write-Host
            Write-Host 'Show Hidden rules for all Users'
            Write-Host
            Write-Host
            Show-HiddenRules
            pause
        }
        2 { cls
            Write-Host
            Write-Host
            Write-Host 'Remove Hidden rules for all Users'
            Write-Host
            Write-Host
            Remove-HiddenRules 
            pause
          }
        3 { cls
            Write-Host
            Write-Host
            Write-Host 'Show All Users rules Brief'
            Write-Host
            Write-Host
            Show-AllRulesBrief 
            pause
          }
        4 { cls
            Write-Host
            Write-Host
            Write-Host 'Show All Users rules Detailed'
            Write-Host
            Write-Host
            Show-DetailedRules 
            pause
          }
        
    }

}Until($Selection -eq 'x') 

Conclusion

In summary, attackers can abuse properties of the Outlook desktop client designed to ease onboarding users and synchronization of the application to Exchange Online to create hidden inbox rules designed to steal or destroy information contained in email messages.

While difficult to detect, using the steps outlined above, organizations may detect, assess, and eradicate any hidden inbox rules deemed a possible threat.

Thanks

Aymen EL JAZIRI (Microsoft MVP)
Aymen EL JAZIRI (Microsoft MVP)

Hi, I’m Aymen El Jaziri , a passionate System Administrator and Microsoft MVP, with years of hands-on experience in managing and securing modern IT infrastructures.
This blog is where I share technical guides, automation scripts, product reviews, and real-world solutions that help IT professionals simplify their day-to-day work and stay ahead in a fast-evolving cloud ecosystem.
Whether you’re here to troubleshoot an issue, improve your automation game, or learn new best practices , welcome in my blog !
Let’s build a stronger, smarter IT community together.
Feel free to connect with me on LinkedIn for more content, discussions, or collaboration opportunities.

Thanks

Aymen

Articles: 154