## https://sploitus.com/exploit?id=6D575D35-4574-521C-A014-D7751E0556C5
# CVE-2026-42897 - Exchange Health Checker Outbound Rewrite Rule Blind Spot
**Severity:** Medium (CVSS 5.3)
**Component:** Microsoft CSS-Exchange - `HealthChecker` diagnostic tool
**Affected Files:**
- `Diagnostics/HealthChecker/Analyzer/Get-URLRewriteRule.ps1` (L49, L72, L97)
- `Diagnostics/HealthChecker/Analyzer/Invoke-AnalyzerIISInformation.ps1` (L442โ459)
**Reported:** 2026-05-15
**References:**
- CSS-Exchange GitHub: `Get-URLRewriteRule.ps1`, `Invoke-AnalyzerIISInformation.ps1`
- EOMT Mitigation Script: `Security/src/EOMT/Mitigations/CVE-2026-42897.ps1` (L147โ254)
---
## Summary
Exchange Health Checker (`HealthChecker.ps1`) reports IIS URL Rewrite rules as part of its
server configuration audit. However, the rule enumeration function `Get-URLRewriteRule.ps1`
only reads **inbound** rules (`system.webServer/rewrite/rules`) and silently ignores
**outbound** rules (`system.webServer/rewrite/outboundRules`).
The EOMT (Exchange On-premises Mitigation Tool) mitigation for CVE-2026-42897 deploys a
Content-Security-Policy header injection rule named `EOMT OWA CSP - outbound` as an IIS
**outbound** URL Rewrite rule. Because Health Checker never reads `outboundRules`, this
mitigation rule is **completely invisible** in Health Checker reports.
An Exchange administrator relying on Health Checker to confirm EOMT mitigations are in place
will receive a report that shows no outbound CSP rule - giving a false negative for
mitigation status and creating a false sense of exposure or, conversely, a false confidence
that no mitigation has been applied when one has.
---
## Vulnerability Detail
### Root Cause
Three distinct code paths in `Get-URLRewriteRule.ps1` all read from `.rewrite.rules` only:
**Path 1 - web.config parsing (L49):**
```powershell
$rules = $content.configuration.'system.webServer'.rewrite.rules
```
**Path 2 - applicationHost.config per-location (L72):**
```powershell
$rules = $location.'system.webServer'.rewrite.rules
```
**Path 3 - applicationHost.config global (L97):**
```powershell
$rules = $ApplicationHostConfig.configuration.'system.webServer'.rewrite.rules
```
None of these paths access `.rewrite.outboundRules`. The returned `$rules` object is then
iterated in `Invoke-AnalyzerIISInformation.ps1` (L442โ459):
```powershell
$displayRewriteRules = ($currentRewriteRules.rule | Where-Object { $_.enabled -ne "false" }).name |
Where-Object { $_ -notcontains $excludeRules }
```
The `.rule` member exists only on the inbound `` collection. Even if `outboundRules`
were read, the display logic would need updating to iterate `.rule` from both collections.
### Affected IIS XML Structure
IIS stores URL Rewrite configuration with two separate children under ``:
```xml
```
### Impact
| Scenario | Effect |
|---|---|
| Admin runs Health Checker after applying EOMT | Report shows no outbound CSP rule โ admin believes mitigation is missing |
| Admin uses Health Checker as the sole audit tool | Cannot verify EOMT outbound rules without inspecting IIS config manually |
| Incident response / compliance checks | Mitigation evidence is absent from Health Checker output |
| Automated monitoring that parses Health Checker JSON | Outbound rule presence / absence is never surfaced |
---
## Proof of Concept
See `poc_cve_2026_42897.ps1` in this directory.
The script:
1. Builds an in-memory mock `web.config` XML with both an inbound rule and the EOMT
`EOMT OWA CSP - outbound` outbound rule.
2. Runs the **vulnerable** Health Checker parsing logic (inbound-only) and shows its output.
3. Runs the **patched** parsing logic (inbound + outbound) and shows the difference.
4. Reproduces all three config paths (web.config, applicationHost per-location, applicationHost global).
```
.\poc_cve_2026_42897.ps1
```
Expected output on a vulnerable (unpatched) Health Checker:
```
[*] Vulnerable path (inbound only):
Rules found: Redirect to HTTPS
MISSING: EOMT OWA CSP - outbound
[*] Patched path (inbound + outbound):
Rules found: Redirect to HTTPS, EOMT OWA CSP - outbound
Outbound rule visible: TRUE
```
---
## Remediation
**Fix in `Get-URLRewriteRule.ps1`** - read both collections at each path:
```powershell
# web.config (L49)
$inbound = $content.configuration.'system.webServer'.rewrite.rules
$outbound = $content.configuration.'system.webServer'.rewrite.outboundRules
$rules = @{ inbound = $inbound; outbound = $outbound }
# applicationHost.config per-location (L72)
$inbound = $location.'system.webServer'.rewrite.rules
$outbound = $location.'system.webServer'.rewrite.outboundRules
$rules = @{ inbound = $inbound; outbound = $outbound }
# applicationHost.config global (L97)
$inbound = $ApplicationHostConfig.configuration.'system.webServer'.rewrite.rules
$outbound = $ApplicationHostConfig.configuration.'system.webServer'.rewrite.outboundRules
$rules = @{ inbound = $inbound; outbound = $outbound }
```
**Fix in `Invoke-AnalyzerIISInformation.ps1`** - iterate both collections:
```powershell
$displayRewriteRules = @()
$displayRewriteRules += ($currentRewriteRules.inbound.rule |
Where-Object { $_.enabled -ne "false" }).name |
Where-Object { $_ -notcontains $excludeRules }
$displayRewriteRules += ($currentRewriteRules.outbound.rule |
Where-Object { $_.enabled -ne "false" }).name |
Where-Object { $_ -notcontains $excludeRules }
```
---
## Timeline
| Date | Event |
|---|---|
| 2026-05-15 | Issue identified during EOMT deployment verification research |
| 2026-05-15 | PoC written and tested against mock IIS config |
---
*FOR AUTHORIZED SECURITY RESEARCH ONLY. Test exclusively in controlled lab environments.*