Checks/MDO/MET-MDO012-SafeDocuments.ps1
|
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', 'METCheckInfo', Justification = 'Check metadata. Read from the AST by Get-METCheck and never executed.')] param() $METCheckInfo = @{ Name = 'Safe Documents' Severity = 'Medium' Description = 'Checks EnableSafeDocs and AllowSafeDocsOpen on Get-AtpPolicyForO365.' RequiresModule = @('ExchangeOnlineManagement') } try { $atpGlobal = Get-AtpPolicyForO365 -ErrorAction Stop } catch { New-METCheckResult -CheckId 'MET-MDO012' -Category MDO -Name 'Safe Documents' ` -Result Fail -Severity Medium -AffectedObject 'Global MDO Settings' ` -Finding 'Unable to retrieve global MDO policy' ` -Recommendation 'Ensure the account has Security Reader or higher permissions.' ` -ReferenceUrl 'https://aka.ms/mdo-safedocuments' -ErrorMessage $_.ToString() return } if (-not $atpGlobal) { New-METCheckResult -CheckId 'MET-MDO012' -Category MDO -Name 'Safe Documents' ` -Result NotApplicable -Severity Medium -AffectedObject 'Global MDO Settings' ` -Finding 'Get-AtpPolicyForO365 returned no object, so neither Safe Documents scanning nor the click-through restriction was established for this tenant. An unconfirmed state is reported as unassessed rather than a pass, because nothing here distinguishes a tenant with Safe Documents protection in place from one without it.' ` -Recommendation 'Ensure the account has Security Reader or higher permissions, then rerun the assessment.' ` -ReferenceUrl 'https://aka.ms/mdo-safedocuments' -ErrorMessage 'Get-AtpPolicyForO365 returned no object.' return } $missingProps = [System.Collections.Generic.List[string]]::new() # A property present but $null was never observed by Exchange Online either - reading # it as $false would fabricate a Fail (EnableSafeDocs) or, worse, a Pass that tells the # reader click-through is blocked when nothing confirmed that (AllowSafeDocsOpen). $enableSafeDocsProperty = $atpGlobal.PSObject.Properties['EnableSafeDocs'] $allowSafeDocsOpenProperty = $atpGlobal.PSObject.Properties['AllowSafeDocsOpen'] if (-not $enableSafeDocsProperty -or $null -eq $enableSafeDocsProperty.Value) { $missingProps.Add('EnableSafeDocs') } if (-not $allowSafeDocsOpenProperty -or $null -eq $allowSafeDocsOpenProperty.Value) { $missingProps.Add('AllowSafeDocsOpen') } if ($missingProps.Count -gt 0) { $propList = $missingProps -join ' and ' $wasWere = if ($missingProps.Count -gt 1) { 'were' } else { 'was' } $controlText = if ($missingProps.Count -gt 1) { 'Safe Documents scanning and the click-through restriction were' } elseif ($missingProps -contains 'EnableSafeDocs') { 'Safe Documents scanning was' } else { 'the click-through restriction was' } $notAPassText = if ($missingProps.Count -gt 1) { 'nothing here distinguishes a tenant with Safe Documents scanning and the click-through restriction both enabled from one with neither' } elseif ($missingProps -contains 'EnableSafeDocs') { 'nothing here distinguishes a tenant that scans files before allowing edit mode from one that does not' } else { 'nothing here distinguishes a tenant that blocks click-through on a file already flagged malicious from one that allows it' } New-METCheckResult -CheckId 'MET-MDO012' -Category MDO -Name 'Safe Documents' ` -Result NotApplicable -Severity Medium -AffectedObject 'Global MDO Settings' ` -Finding "$propList $wasWere not returned by the global MDO policy, so whether $controlText enabled for this tenant was not established. An unconfirmed state is reported as unassessed rather than a pass, because $notAPassText." ` -Recommendation "Confirm the setting directly with: Get-AtpPolicyForO365 | Format-List EnableSafeDocs, AllowSafeDocsOpen. An absent property usually means an ExchangeOnlineManagement version that does not expose it - update the module and rerun the assessment. Safe Documents also requires Microsoft 365 A5 or E5 Security licensing; on a tenant without that licensing these properties may legitimately not be surfaced, which is why this is reported as unassessed rather than as a pass or a failure." ` -ReferenceUrl 'https://aka.ms/mdo-safedocuments' ` -ErrorMessage "The global MDO policy did not return: $propList." return } $issues = [System.Collections.Generic.List[string]]::new() if (-not $atpGlobal.EnableSafeDocs) { $issues.Add('Safe Documents is disabled - Office files opened in Protected View are not scanned before allowing edit mode') } if ($atpGlobal.AllowSafeDocsOpen) { $issues.Add('Users are allowed to click through Protected View even when Safe Documents identifies the file as malicious') } if ($issues.Count -gt 0) { New-METCheckResult -CheckId 'MET-MDO012' -Category MDO -Name 'Safe Documents' ` -Result Fail -Severity Medium -AffectedObject 'Global MDO Settings' ` -Finding ($issues -join '; ') ` -Recommendation 'Run: Set-AtpPolicyForO365 -EnableSafeDocs $true -AllowSafeDocsOpen $false. Safe Documents requires Microsoft 365 A5 or E5 Security licensing. When enabled, files opened in Protected View are scanned before users can exit Protected View.' ` -ReferenceUrl 'https://aka.ms/mdo-safedocuments' } else { New-METCheckResult -CheckId 'MET-MDO012' -Category MDO -Name 'Safe Documents' ` -Result Pass -Severity Medium -AffectedObject 'Global MDO Settings' ` -Finding 'Safe Documents is enabled and click-through for malicious files is blocked' ` -ReferenceUrl 'https://aka.ms/mdo-safedocuments' } |