Skip to content

Harden backup/undo safety nets in security-feature modules (v1.121.12)#80

Merged
TheAbider merged 1 commit into
masterfrom
fix/backup-undo-safety-net
Jul 1, 2026
Merged

Harden backup/undo safety nets in security-feature modules (v1.121.12)#80
TheAbider merged 1 commit into
masterfrom
fix/backup-undo-safety-net

Conversation

@TheAbider

Copy link
Copy Markdown
Owner

Fixes from an adversarial audit of the security-feature modules (Group Policy, JEA, NPS, SIEM). One coherent class: a backup/snapshot taken with -EA SilentlyContinue (or its result discarded), then trusted downstream — so a silently-failed backup made the exit code lie, missed drift, or made an "undo" destroy the live config. 4 finder findings were refuted and dropped.

SIEM forwarder (76)

  • Undo can't delete your live config anymore (LOW, but sharp). Write-SIEMConfigFile returned the backup path with Ok=$true even when the Copy-Item backup silently failed; Restore-SIEMConfig then saw the missing backup, fell through, and Remove-Item'd the just-written config on undo — silently stopping log forwarding. It now fails closed: if it can't back up an existing config, it doesn't overwrite it, so a non-null Backup always means a real backup exists.

Group Policy (71)

  • GPOBackup exits non-zero when it backed up nothing (MED). GPOs enumerated but every Backup-GPO failed → still exit 0, leaving an empty folder trusted as a drift/restore baseline. Now returns $null → exit 1.
  • Drift stops hiding real changes (MED). A GPO whose baseline settings XML was missing was counted unchanged (false all-clear). It's now tracked in an Indeterminate bucket and surfaced as "not checked".
  • Restore undo only registered when the pre-restore snapshot succeeded (LOW) — previously the undo pointed at a possibly-empty folder and no-op'd silently; the dry-run undo now also verifies snapshot content.

NPS (73)

  • Import verifies the pre-import backup landed (LOW) before printing "Pre-import backup: …" and registering the undo; warns plainly when the import isn't undoable.

JEA (72)

  • Dry-run apply throws on validation failure (LOW). Invoke-JEAEndpointBuild returns $false without throwing when the .pssc fails validation; the dry-run engine marks a non-throwing apply as "applied", so a rejected endpoint was reported registered. It now throws.

Verified clean (no changes)

  • JEA role/endpoint config is least-privilege + correctly constrained (RunAsVirtualAccount scoped, RestrictedRemoteServer, NoLanguage). The AlwaysOn VPN / RADIUS policy values are correct.

Verification

  • New Section 199 (10 asserts). Structural 5341/5341; full Pester 312/312; PSSA 0. Monolithic rebuilt, parse check passed. Version → 1.121.12.

Fixes from an adversarial audit of the security-feature modules (GPO, JEA, NPS,
SIEM). Common class: a backup/snapshot taken with -EA SilentlyContinue (or its
result discarded), then trusted downstream as if it exists.

76-SIEMForwarder.ps1:
- Write-SIEMConfigFile fails closed if it can't back up an existing config, so
  Restore-SIEMConfig (undo) can never fall through and DELETE the live config when
  the backup silently failed -- which was silently stopping log forwarding.

71-GPOManager.ps1:
- GPO backup returns $null (CLI exit 1) when GPOs were enumerated but every
  Backup-GPO failed, instead of exiting 0 with an empty folder trusted as a baseline.
- Drift detection tracks an Indeterminate bucket: a GPO whose baseline settings XML
  is missing is reported as 'not checked', not silently 'unchanged' (missed drift).
- The undoable GPO restore only registers an undo when the pre-restore snapshot
  actually succeeded; the dry-run undo verifies snapshot content before restoring.

73-NPS.ps1:
- NPS config import verifies the pre-import backup landed before claiming it and
  registering the undo; warns plainly when the import isn't undoable.

72-JEA.ps1:
- The dry-run Apply throws when Invoke-JEAEndpointBuild returns $false (validation
  failure returns without throwing), so a failed endpoint isn't marked applied.

Audit also confirmed the JEA role/endpoint config is least-privilege + constrained
and the VPN/RADIUS policy values are correct.

Tests: Section 199 (10 asserts). Structural 5341/5341; Pester 312/312; PSSA 0.
Version stamps -> 1.121.12.
@codecov

codecov Bot commented Jul 1, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@TheAbider TheAbider merged commit 9e0a048 into master Jul 1, 2026
7 checks passed
@TheAbider TheAbider deleted the fix/backup-undo-safety-net branch July 1, 2026 15:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant