From 787c66e0099ceffecea0be0b865426e303c5fd26 Mon Sep 17 00:00:00 2001 From: Shirofune-Security <43838376+Shirofune-Security@users.noreply.github.com> Date: Sat, 19 Sep 2026 07:31:23 +0900 Subject: [PATCH] Normalize WEF XML evidence before PowerShell 5.1 JSON serialization --- .github/workflows/wef-deployment.yml | 19 +++++++++++++------ scripts/WefDeployment.ps1 | 5 ++++- tests/WefDeployment.Tests.ps1 | 1 + 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/.github/workflows/wef-deployment.yml b/.github/workflows/wef-deployment.yml index b02b7294..b81482c3 100644 --- a/.github/workflows/wef-deployment.yml +++ b/.github/workflows/wef-deployment.yml @@ -9,18 +9,25 @@ permissions: jobs: wef-deployment: runs-on: windows-latest + timeout-minutes: 15 steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Safe public command fixtures in Windows PowerShell 5.1 shell: powershell - run: | - ./tests/WefDeployment.Tests.ps1 - ./tests/WefDeployment.Cli.Tests.ps1 + timeout-minutes: 3 + run: ./tests/WefDeployment.Tests.ps1 + - name: Public CLI rejection checks in Windows PowerShell 5.1 + shell: powershell + timeout-minutes: 3 + run: ./tests/WefDeployment.Cli.Tests.ps1 - name: Safe public command fixtures in PowerShell 7 shell: pwsh - run: | - ./tests/WefDeployment.Tests.ps1 - ./tests/WefDeployment.Cli.Tests.ps1 + timeout-minutes: 3 + run: ./tests/WefDeployment.Tests.ps1 + - name: Public CLI rejection checks in PowerShell 7 + shell: pwsh + timeout-minutes: 3 + run: ./tests/WefDeployment.Cli.Tests.ps1 - name: Native read-only smoke in Windows PowerShell 5.1 shell: powershell run: ./tests/WefDeployment.Windows.Tests.ps1 diff --git a/scripts/WefDeployment.ps1 b/scripts/WefDeployment.ps1 index dd9829ed..f44cd1b7 100644 --- a/scripts/WefDeployment.ps1 +++ b/scripts/WefDeployment.ps1 @@ -32,7 +32,10 @@ function Get-WelaWefControlState { 'Subscription' { $ids = @((Invoke-WelaNative -FilePath 'wecutil.exe' -Arguments @('es')).Output | ForEach-Object { $_.ToString().Trim() } | Where-Object { $_ }) if ($ids -notcontains $Target.Id) { return [pscustomobject]@{ Exists=$false; Xml=$null; Key=$null; Definition=$null } } - $xml = (Invoke-WelaNative -FilePath 'wecutil.exe' -Arguments @('gs',$Target.Id,'/f:xml')).Diagnostic + # Keep evidence as a plain string. Windows PowerShell 5.1's JSON + # serializer expands ETS properties on strings (for example a test + # reader's PSDrive/PSProvider graph), unlike modern PowerShell. + $xml = [string]::Concat((Invoke-WelaNative -FilePath 'wecutil.exe' -Arguments @('gs',$Target.Id,'/f:xml')).Diagnostic) $model = ConvertFrom-WelaWefSubscription -Xml $xml -SourceSids $Target.SourceSids -Observed return [pscustomobject]@{ Exists=$true; Xml=$xml; Key=$model.Key; Definition=$model.Definition } } diff --git a/tests/WefDeployment.Tests.ps1 b/tests/WefDeployment.Tests.ps1 index c1916792..ebb74a95 100644 --- a/tests/WefDeployment.Tests.ps1 +++ b/tests/WefDeployment.Tests.ps1 @@ -202,6 +202,7 @@ try { $global:WelaWefFixture.Forwarded=$false $report=Invoke-Collector -ResultsPath (Join-Path $temp 'collector-result.json') Assert ($report.ExitCode -eq 0 -and $global:WelaWefFixture.Subs.Count -eq 1) 'Verified collector creates only the selected explicit subscription' + Assert ($null -eq $report.Subscriptions[0].ObservedSubscription.Xml.PSObject.Properties['PSDrive']) 'Observed XML strips reader ETS metadata before Windows PowerShell 5.1 JSON serialization' Assert ($report.Subscriptions[0].Runtime.Raw -eq 'Localized runtime fixture' -and $report.Subscriptions[0].EventArrival -eq 'Not tested') 'Native runtime evidence is retained without inventing successful arrivals' Assert ($report.Subscriptions[0].ChannelObservationLocation -like 'Collector only*') 'Collector channel inventory is not misrepresented as remote source state' $beforeWrites=$global:WelaWefFixture.Writes.Count; $script:backup=Join-Path $temp ([guid]::NewGuid().ToString('N')); $global:WelaWefFixture.Backup=$backup