EvolitBlogKontakt

Exchange Online Protection: jak diagnozować i naprawiać fałszywe pozytywy w kwarantannie

EOP regularnie blokuje legitymne wiadomości od partnerów, powiadomienia systemowe i maile z Gmaila — z powodu agresywnych reguł filtrowania lub braku uwierzytelniania domeny. Pokazujemy jak w ciągu 5 minut ustalić przyczynę, masowo zwolnić wiadomości przez PowerShell i skonfigurować środowisko tak, żeby problem nie wracał.

Exchange Online Protection: jak diagnozować i naprawiać fałszywe pozytywy w kwarantannie

TL;DR: EOP regularnie blokuje legitymne wiadomości jako spam lub phishing — w tym maile od partnerów biznesowych, powiadomienia systemowe i wiadomości z Gmaila. Ten artykuł pokazuje jak w ciągu 5 minut ustalić dlaczego wiadomość trafiła do kwarantanny, jak ją stamtąd wyciągnąć (w tym masowo przez PowerShell) i jak skonfigurować środowisko tak, żeby problem nie wracał co tydzień.

Problem

Incydent EX1227432 z lutego 2026 roku — kiedy Microsoft wdrożył zbyt agresywną regułę wykrywania URL-i i przez 5 dni blokował legitymne wiadomości biznesowe organizacji na całym świecie — to nie był wyjątek. To był kolejny przykład z długiej listy. Przed nim był EX1064599, gdzie wiadomości z Gmaila trafiały masowo do kwarantanny z etykietą "High Confidence Phish" i wynikiem SCL 8. Wcześniej, w 2025 roku, seria incydentów gdzie maile z powiadomieniami o naruszeniach bezpieczeństwa były blokowane przez EOP — co szczególnie boli administratorów odpowiedzialnych za bezpieczeństwo.

W praktyce wygląda to tak: pracownik zgłasza, że nie dostał faktury od dostawcy. Sprawdzasz skrzynkę — nie ma. Sprawdzasz folder Wiadomości-śmieci — nie ma. Po 15 minutach szukania okazuje się, że leży w kwarantannie z powodem "High confidence phishing". Dostawca wysyła z tej samej domeny od lat, a EOP nagle postanowił, że to phishing.

Problem dotyka szczególnie:

  • wiadomości od dostawców używających zewnętrznych platform wysyłkowych (Mailchimp, SendGrid, Shopify) z domeną klienta bez poprawnego DKIM,
  • powiadomień systemowych z Azure, monitoringu, pipeline'ów CI/CD,
  • maili od małych firm hostowanych na współdzielonych serwerach z generycznym SPF,
  • wiadomości zawierających wiele linków lub duże obrazki w stopce (wysoki BCL),
  • podczas globalnych incydentów po stronie Microsoft, kiedy nagle rośnie liczba fałszywych trafień u wszystkich klientów jednocześnie.

Ten typ problemu jest frustrujący z jeszcze jednego powodu: użytkownicy często w ogóle nie wiedzą, że coś do nich nie dotarło. Nie dostają powiadomień o kwarantannie (chyba że quarantine notifications są włączone), więc milczenie odbierają jako brak odpowiedzi od nadawcy.

Dlaczego tak się dzieje

EOP ocenia każdą wiadomość przychodzącą przez kilka filtrów i przypisuje jej wynik SCL (Spam Confidence Level) w skali od -1 do 9. Wyższy wynik = większe prawdopodobieństwo spamu lub phishingu. Progi działania:

  • SCL -1: wiadomość pochodzi z zaufanego źródła, filtrowanie pominięte
  • SCL 0-4: nie spam
  • SCL 5-6: spam -> folder Wiadomości-śmieci
  • SCL 7-9: wysoka pewność spam lub phishing -> kwarantanna

Poza SCL, EOP analizuje BCL (Bulk Complaint Level, skala 0-9 — wartości powyżej 7 oznaczają kwarantannę dla wiadomości masowych) oraz PCL (Phish Confidence Level). Wyniki trafiają do nagłówka X-Forefront-Antispam-Report.

Kluczowe jest uwierzytelnianie wiadomości. Jeśli domena nadawcy nie ma poprawnych rekordów SPF, DKIM i DMARC, pojawia się wynik compauth=fail reason=001 w nagłówku Authentication-Results. To sygnał dla EOP, że nadawca może być sfałszowany. Nawet jeśli wiadomość pochodzi od prawdziwego, zaufanego nadawcy — brak lub błędna konfiguracja DNS sprawia, że EOP nie ma jak tego zweryfikować.

Drugi powód to globalne aktualizacje reguł wdrażane przez Microsoft bez wcześniejszego ogłoszenia. Nowa reguła wchodzi w życie i od tego dnia zaczyna blokować wiadomości, które przez poprzednie miesiące przechodziły bez problemu. Jedynym sygnałem jest wzrost zgłoszeń od użytkowników.

Trzecia przyczyna to heurystyki kontentowe: wiele linków w jednej wiadomości, obrazki osadzone w HTML, stopki formatowane przez zewnętrzne narzędzia marketingowe, a nawet specyficzne kombinacje słów kluczowych w temacie — to wszystko podnosi SCL i BCL niezależnie od konfiguracji DNS.

Rozwiązanie krok po kroku

Krok 1: Sprawdź Service Health przed jakimkolwiek działaniem

Zanim zaczniesz szukać problemu u siebie, 60 sekund na sprawdzenie Service Health: Microsoft 365 admin center -> Health -> Service health -> Exchange Online. Jeśli widzisz aktywny incydent z opisem dotyczącym filtrowania lub kwarantanny, masz odpowiedź — czekasz na Microsoft i w międzyczasie ręcznie zwalniasz konkretne wiadomości z kwarantanny. Nie ma sensu konfigurować reguł transportu na czas incydentu po stronie Microsoft.

Krok 2: Zlokalizuj wiadomość i przeanalizuj nagłówki

Portal: https://security.microsoft.com/quarantine

Albo przez PowerShell — znacznie szybsze przy masowych zdarzeniach:

# Połącz z Exchange Online
Connect-ExchangeOnline -UserPrincipalName admin@twojafirma.pl

# Wyszukaj wiadomości z ostatnich 7 dni od konkretnego nadawcy
Get-QuarantineMessage -SenderAddress "faktura@dostawca.pl" `
    -StartReceivedDate (Get-Date).AddDays(-7) `
    -EndReceivedDate (Get-Date) | `
    Select-Object ReceivedTime, SenderAddress, Subject, QuarantineTypes, Expires

# Sprawdź wszystkie wiadomości w kwarantannie z ostatnich 24h pogrupowane według powodu
Get-QuarantineMessage -StartReceivedDate (Get-Date).AddDays(-1) | `
    Group-Object QuarantineTypes | `
    Select-Object Name, Count

Gdy znajdziesz wiadomość, sprawdź jej nagłówki. W portalu: zaznacz wiadomość -> View message header. Kluczowe pola:

  • X-Forefront-Antispam-Report — szukaj SCL=, CAT=, SFV=:
    • CAT:HPHISH = high-confidence phishing (najgorsza kategoria — tylko admin może zwolnić)
    • CAT:BULK = wiadomość masowa
    • SFV:SPM = spam na podstawie treści
    • SFV:SKQ = wiadomość była w kwarantannie i już raz zwolniona
    • SFV:SKB = zablokowany nadawca lub domena
  • Authentication-Results — sprawdź wyniki spf=, dkim=, dmarc=:
    • compauth=fail reason=001 = niepowodzenie composite auth = problem z konfiguracją DNS nadawcy
    • spf=fail lub spf=permerror = błędny rekord SPF (permerror = przekroczony limit 10 DNS lookupów)
  • X-Microsoft-Antispam — pole BCL= (Bulk Complaint Level, 0-9; powyżej 7 = kwarantanna dla bulk)

Przydatne narzędzie online: Microsoft Message Header Analyzer (mha.azurewebsites.net) — wklej surowe nagłówki, a otrzymasz czytelną tabelę z wszystkimi wynikami.

Krok 3: Zwolnij wiadomości z kwarantanny

Przez portal — dla pojedynczych wiadomości: security.microsoft.com/quarantine -> zaznacz wiadomość -> Release -> zaznacz "Submit to Microsoft for analysis" (zalecane — pomaga Microsoft nauczyć się, że to fałszywy pozytyw).

Przez PowerShell — przy masowych incydentach:

# Zwolnij wszystkie wiadomości od konkretnego nadawcy do wszystkich odbiorców
Get-QuarantineMessage -SenderAddress "faktura@dostawca.pl" `
    -PageSize 1000 | `
    Release-QuarantineMessage -ReleaseToAll

# Zwolnij dla konkretnego odbiorcy z ostatnich 48h
Get-QuarantineMessage `
    -RecipientAddress "jan.kowalski@twojafirma.pl" `
    -StartReceivedDate (Get-Date).AddDays(-2) | `
    Release-QuarantineMessage -ReleaseToAll

# Zgłoś false positive do Microsoft po zwolnieniu
Get-QuarantineMessage -SenderAddress "faktura@dostawca.pl" `
    -StartReceivedDate (Get-Date).AddDays(-7) | `
    ForEach-Object { Submit-QuarantineMessage -Identity $_.Identity -ReportType NotJunk }

Ważne ograniczenie: Wiadomości sklasyfikowane jako High Confidence Phishing lub Malware mogą zwolnić TYLKO administratorzy. Użytkownicy mogą jedynie wysłać prośbę o zwolnienie, a admin musi ją zatwierdzić. Nawet odpowiednio skonfigurowana quarantine policy nie daje użytkownikom możliwości samodzielnego zwalniania HPHISH.

Czas przechowywania w kwarantannie (domyślnie):

  • Spam: 15 dni
  • Phishing, High Confidence Phishing, Malware: 30 dni

Po tym czasie wiadomości są trwale usuwane — brak możliwości odzyskania.

Krok 4: Dodaj nadawcę do Tenant Allow/Block List

Dobre rozwiązanie tymczasowe, na czas zanim nadawca poprawi konfigurację DNS:

# Dodaj konkretny adres email do listy zezwoleń
New-TenantAllowBlockListItems `
    -ListType Sender `
    -Entries "faktura@dostawca.pl" `
    -Allow `
    -ExpirationDate (Get-Date).AddDays(45) `
    -Notes "Zaufany dostawca - oczekujemy na konfigurację DKIM/DMARC"

# Dodaj całą domenę (ostrożnie - szerokie uprawnienie)
New-TenantAllowBlockListItems `
    -ListType Sender `
    -Entries "dostawca.pl" `
    -Allow `
    -ExpirationDate (Get-Date).AddDays(45)

Limity wpisów TABL zależą od licencji:

  • Bez Defender for Office 365: maksymalnie 500 allow entries łącznie
  • Defender for Office 365 Plan 1: maksymalnie 1000 allow entries
  • Defender for Office 365 Plan 2: maksymalnie 5000 allow entries

Krok 5: Stwórz regułę mail flow jako rozwiązanie długoterminowe

Dla zaufanych partnerów lub systemów, których konfiguracji DNS nie kontrolujesz:

# Bypass filtrów antyspamowych dla zaufanej domeny partnera
New-TransportRule `
    -Name "EOP Bypass - Zaufany partner XYZ" `
    -SenderDomainIs "zaufanypartner.pl" `
    -SetSCL -1 `
    -Comments "Zaufany dostawca faktur - SCL bypass do czasu naprawy SPF/DKIM"

# Sprawdź istniejące reguły transportu i ich priorytety
Get-TransportRule | Select-Object Name, Priority, State, SetSCL | Sort-Object Priority

Krok 6: Napraw uwierzytelnianie (rozwiązanie docelowe)

Jeśli problem dotyczy twojej domeny lub domeny klienta, któremu administrujesz, poprawna konfiguracja SPF + DKIM + DMARC eliminuje problem u źródła.

SPF (rekord TXT w DNS):

v=spf1 include:spf.protection.outlook.com -all

Uwaga: SPF ma twardy limit 10 DNS lookupów. Jeśli korzystasz z wielu usług zewnętrznych (SendGrid, Mailchimp, Zendesk), łatwo go przekroczyć, co skutkuje spf=permerror — traktowanym przez EOP jako błąd, nie neutralny wynik.

DKIM — włącz przez PowerShell:

# Wygeneruj klucze DKIM dla domeny
New-DkimSigningConfig -DomainName "twojadomena.pl" -Enabled $true

# Pobierz rekordy CNAME do dodania w DNS
Get-DkimSigningConfig -Identity "twojadomena.pl" | `
    Select-Object Selector1CNAME, Selector2CNAME, Status

Po wygenerowaniu CNAME dodaj je w DNS u dostawcy domeny i poczekaj do 48h na propagację.

DMARC (rekord TXT w DNS):

v=DMARC1; p=quarantine; rua=mailto:dmarc@twojadomena.pl; pct=100

Zacznij od p=none jeśli nie jesteś pewien konfiguracji SPF/DKIM — to tryb monitorowania bez blokowania.

Typowe pułapki i edge cases

Pułapka 1: SCL -1 w regule transportu nie działa na HPHISH.

Tworzysz regułę z SetSCL -1 i zakładasz, że problem rozwiązany. Wiadomości nadal trafiają do kwarantanny — bo klasyfikacja CAT:HPHISH nadpisuje wynik SCL z mail flow rule. Reguły transportu nie mają wpływu na filtrowanie high-confidence phishingu i malware. Musisz dodatkowo dodać domenę do TABL lub zmodyfikować anti-phish policy:

# Sprawdź polityki anti-phish i aktualne ustawienia
Get-AntiPhishPolicy | Select-Object Name, EnableAntiSpoofEnforcement, AuthenticationFailAction

# Zmień akcję dla niepowodzenia uwierzytelniania z Quarantine na MoveToJunk
Set-AntiPhishPolicy -Identity "Default" -AuthenticationFailAction MoveToJunk

Pułapka 2: Wpisy TABL wygasają po 45 dniach i nikt tego nie monitoruje.

Wpisy allow w TABL domyślnie wygasają 45 dni po tym, jak system filtrowania ostatni raz oceni nadawcę jako "czysty". Nie masz kontroli nad dokładnym momentem wygaśnięcia — zależy od aktywności filtrowania. Dodaj monitoring:

# Sprawdź wpisy TABL wygasające w ciągu 7 dni
Get-TenantAllowBlockListItems -ListType Sender -Allow | `
    Where-Object { $_.ExpirationDate -lt (Get-Date).AddDays(7) } | `
    Select-Object Value, ExpirationDate, Notes | `
    Sort-Object ExpirationDate

Pułapka 3: Get-MessageTrace obejmuje tylko ostatnie 10 dni.

Dostajesz zgłoszenie: "nie dostałem maila sprzed 2 tygodni". Get-MessageTrace nie znajdzie nic — cmdlet obejmuje tylko ostatnie 10 dni. Do starszych wiadomości potrzebujesz Start-HistoricalSearch, który jest operacją asynchroniczną — wyniki dostępne po ok. 30 minutach w sekcji Message Trace w centrum administracyjnym M365. Przy pilnych przypadkach: poinformuj użytkownika z wyprzedzeniem, że diagnostyka zajmie czas.

Pułapka 4: Zarządzanie kwarantanną przez role PIM nie działa.

Jeśli w twojej organizacji role administratorów są aktywowane przez Azure Privileged Identity Management (PIM), musisz wiedzieć że Microsoft jawnie dokumentuje brak wsparcia dla PIM w interfejsie kwarantanny (zmiana wprowadzona w lutym 2023, MC447339). Rola aktywowana przez PIM nie daje dostępu do zarządzania kwarantanną. Potrzebujesz permanentnie przydzielonej roli Security Administrator lub skorzystania z dedykowanego konta technicznego.

Pułapka 5: Outbound spam to osobny problem z osobną procedurą.

Jeśli EOP blokuje wychodzące wiadomości (przejęte konto wysyłające spam), konto trafia na listę "Restricted Entities" w security.microsoft.com/restrictedentities. To jest INNY mechanizm niż inbound quarantine — żadna z powyższych metod nie pomoże. Procedura: zmień hasło użytkownika, sprawdź reguły przekierowania skrzynki (to klasyczny objaw przejętego konta), usuń konto z Restricted Entities i przejrzyj Unified Audit Log pod kątem nieautoryzowanej aktywności.

Podsumowanie

  • Pierwsze działanie: sprawdź Service Health — globalny incydent Microsoft nie wymaga konfiguracji po twojej stronie, tylko ręcznego zwalniania wiadomości
  • Diagnoza przyczyny: nagłówek X-Forefront-Antispam-Report (pola SCL=, CAT=, SFV=) + Authentication-Results (compauth=fail reason=001 = problem DNS nadawcy)
  • Szybkie zwolnienie: Get-QuarantineMessage | Release-QuarantineMessage -ReleaseToAll + zgłoszenie false positive do Microsoft przez Submit-QuarantineMessage
  • Ochrona krótkoterminowa: Tenant Allow/Block List (pamiętaj o 45-dniowym wygaśnięciu i limitach 500/1000/5000 wpisów) lub mail flow rule z SCL -1 (nieskuteczne dla HPHISH)
  • Rozwiązanie docelowe: poprawna konfiguracja SPF + DKIM + DMARC po stronie domeny nadawcy — to jedyne rozwiązanie eliminujące problem na stałe