setNewDiagPath(e.target.value)}
onKeyDown={(e) => { if (e.key === "Enter") { e.preventDefault(); addPath(); } }}
diff --git a/src/Web/autopilot-monitor-web/app/settings/components/DiagnosticsSection.tsx b/src/Web/autopilot-monitor-web/app/settings/components/DiagnosticsSection.tsx
index 7d274e1f..102e94a9 100644
--- a/src/Web/autopilot-monitor-web/app/settings/components/DiagnosticsSection.tsx
+++ b/src/Web/autopilot-monitor-web/app/settings/components/DiagnosticsSection.tsx
@@ -304,7 +304,7 @@ export default function DiagnosticsSection({
setNewDiagPath(e.target.value)}
onKeyDown={(e) => { if (e.key === "Enter") { e.preventDefault(); addTenantPath(); } }}
diff --git a/src/Web/autopilot-monitor-web/utils/__tests__/guardValidation.test.ts b/src/Web/autopilot-monitor-web/utils/__tests__/guardValidation.test.ts
index 76b9286e..e75b4012 100644
--- a/src/Web/autopilot-monitor-web/utils/__tests__/guardValidation.test.ts
+++ b/src/Web/autopilot-monitor-web/utils/__tests__/guardValidation.test.ts
@@ -410,6 +410,32 @@ describe("validateDiagnosticsPath", () => {
const r = validateDiagnosticsPath("C:\\Windows\\System32\\winevt\\Logs\\System.evtx", false);
expect(r.allowed).toBe(true);
});
+
+ it.each([
+ "C:\\Windows\\System32\\winevt\\Logs\\Security.evtx",
+ "C:\\Windows\\System32\\winevt\\Logs\\security.EVTX",
+ "C:\\Windows\\System32\\winevt\\Logs\\Microsoft-Windows-PowerShell%4Operational.evtx",
+ "C:\\Windows\\System32\\winevt\\Logs\\Windows PowerShell.evtx",
+ "C:\\Windows\\System32\\winevt\\Logs\\Microsoft-Windows-Sysmon%4Operational.evtx",
+ "C:\\Windows\\System32\\winevt\\Logs\\Archive-Security-2026-09-21-10-15-30-123.evtx",
+ "C:\\Install\\Log\\Security.evtx",
+ ])("blocks the hard-blocked event log %s in every mode", (path) => {
+ expect(validateDiagnosticsPath(path, false).allowed).toBe(false);
+ const unrestricted = validateDiagnosticsPath(path, true);
+ expect(unrestricted.allowed).toBe(false);
+ expect(unrestricted.reason).toContain("never readable");
+ });
+
+ it("does not mistake a neighbouring channel for a blocked one", () => {
+ const dsc =
+ "C:\\Windows\\System32\\winevt\\Logs\\Microsoft-Windows-PowerShell-DesiredStateConfiguration-FileDownloadManager%4Operational.evtx";
+ expect(validateDiagnosticsPath(dsc, false).allowed).toBe(true);
+ expect(validateDiagnosticsPath("C:\\Windows\\Logs\\SecurityAudit.evtx", false).allowed).toBe(true);
+ });
+
+ it("leaves an .evtx wildcard allowed — the agent skips blocked files one by one", () => {
+ expect(validateDiagnosticsPath("C:\\Windows\\System32\\winevt\\Logs\\*.evtx", false).allowed).toBe(true);
+ });
});
// ---------------------------------------------------------------------------
diff --git a/src/Web/autopilot-monitor-web/utils/guardValidation.ts b/src/Web/autopilot-monitor-web/utils/guardValidation.ts
index aec81090..59738f04 100644
--- a/src/Web/autopilot-monitor-web/utils/guardValidation.ts
+++ b/src/Web/autopilot-monitor-web/utils/guardValidation.ts
@@ -457,6 +457,19 @@ export function validateDiagnosticsPath(
return { allowed: false, reason: `${hardBlockedDiag} is always blocked (protected system path)`, unrestricted: false };
}
+ // Hard-blocked event logs (even in unrestricted mode). Only a path that names the
+ // file is caught here; for a wildcard the agent skips these files one by one.
+ const blockedChannel = findBlockedEventLogFile(
+ normalizedDir.substring(normalizedDir.lastIndexOf("\\") + 1)
+ );
+ if (blockedChannel) {
+ return {
+ allowed: false,
+ reason: `"${blockedChannel}" is never readable — it carries the audit trail or script-block logging`,
+ unrestricted: false,
+ };
+ }
+
if (unrestrictedMode) {
return { allowed: true, reason: "All paths allowed in unrestricted mode (except blocked system paths)", unrestricted: true };
}
@@ -497,6 +510,22 @@ function matchesChannel(channel: string, prefix: string): boolean {
return c === p || c.startsWith(p + "/");
}
+// Windows archives a full channel as "Archive--yyyy-MM-dd-HH-mm-ss-fff.evtx".
+const ARCHIVED_EVENT_LOG = /^Archive-(.+)-\d{4}-\d{2}-\d{2}-\d{2}-\d{2}-\d{2}-\d{3}$/i;
+
+/**
+ * The blocked channel an .evtx file name belongs to (live or archived file; "%4" in the
+ * name encodes "/"), or undefined. Mirrors DiagnosticsPathGuards.IsHardBlockedEventLogFile.
+ */
+function findBlockedEventLogFile(fileName: string): string | undefined {
+ if (!fileName.toLowerCase().endsWith(".evtx")) return undefined;
+ let stem = fileName.slice(0, -".evtx".length);
+ const archived = ARCHIVED_EVENT_LOG.exec(stem);
+ if (archived) stem = archived[1];
+ const channel = stem.replace(/%4/g, "/").trim();
+ return BLOCKED_EVENT_LOG_CHANNELS.find((b) => matchesChannel(channel, b));
+}
+
export function validateEventLogTarget(
target: string,
unrestrictedMode: boolean