From 09ec2d10434f77438e79757a97730eac894d6fde Mon Sep 17 00:00:00 2001 From: Anatoli Beliaev Date: Thu, 30 Apr 2026 23:22:06 -0700 Subject: [PATCH 1/2] Suppress CodeQL warnings for LocalOrchestrationService regarding serialization security in in-proc testing context Co-authored-by: Copilot --- .../LocalOrchestrationService.cs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/DurableTask.Emulator/LocalOrchestrationService.cs b/src/DurableTask.Emulator/LocalOrchestrationService.cs index 50e43ecd5..3cfa101f9 100644 --- a/src/DurableTask.Emulator/LocalOrchestrationService.cs +++ b/src/DurableTask.Emulator/LocalOrchestrationService.cs @@ -21,6 +21,7 @@ namespace DurableTask.Emulator using System; using System.Collections.Concurrent; using System.Collections.Generic; + using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Text; using System.Threading; @@ -54,6 +55,21 @@ public class LocalOrchestrationService : IOrchestrationService, IOrchestrationSe readonly object timerLock = new object(); readonly ConcurrentDictionary> orchestrationWaiters; + + // CodeQL [SM02211] False positive. LocalOrchestrationService is a fully in-proc emulator intended for + // testing only. The bytes produced by SerializeOrchestrationRuntimeState are stored in the in-memory + // sessionState dictionary on this same instance and never cross a trust boundary (no disk, network, + // or cross-process surface). The polymorphic surface is bounded to HistoryEvent subclasses defined in + // DurableTask.Core; customer payload fields (Input/Output/Result/Reason/Details) are typed as string + // and are opaque to this serializer. No attacker-controlled JSON can reach DeserializeOrchestrationRuntimeState. + [SuppressMessage( + "Security", + "CA2326:Do not use TypeNameHandling values other than None", + Justification = "In-proc test-only emulator; serialized bytes never cross a trust boundary. See inline CodeQL suppression comment above.")] + [SuppressMessage( + "Security", + "CA2327:Do not use insecure deserializer settings", + Justification = "In-proc test-only emulator; serialized bytes never cross a trust boundary. See inline CodeQL suppression comment above.")] static readonly JsonSerializerSettings StateJsonSettings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto }; /// From 3523a5c517416b37ed6a6436488b62abe483a5ec Mon Sep 17 00:00:00 2001 From: Anatoli Beliaev Date: Fri, 1 May 2026 11:09:33 -0700 Subject: [PATCH 2/2] Fix suppression syntax Co-authored-by: Copilot --- .../LocalOrchestrationService.cs | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/src/DurableTask.Emulator/LocalOrchestrationService.cs b/src/DurableTask.Emulator/LocalOrchestrationService.cs index 3cfa101f9..32ebea257 100644 --- a/src/DurableTask.Emulator/LocalOrchestrationService.cs +++ b/src/DurableTask.Emulator/LocalOrchestrationService.cs @@ -21,7 +21,6 @@ namespace DurableTask.Emulator using System; using System.Collections.Concurrent; using System.Collections.Generic; - using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Text; using System.Threading; @@ -56,20 +55,7 @@ public class LocalOrchestrationService : IOrchestrationService, IOrchestrationSe readonly ConcurrentDictionary> orchestrationWaiters; - // CodeQL [SM02211] False positive. LocalOrchestrationService is a fully in-proc emulator intended for - // testing only. The bytes produced by SerializeOrchestrationRuntimeState are stored in the in-memory - // sessionState dictionary on this same instance and never cross a trust boundary (no disk, network, - // or cross-process surface). The polymorphic surface is bounded to HistoryEvent subclasses defined in - // DurableTask.Core; customer payload fields (Input/Output/Result/Reason/Details) are typed as string - // and are opaque to this serializer. No attacker-controlled JSON can reach DeserializeOrchestrationRuntimeState. - [SuppressMessage( - "Security", - "CA2326:Do not use TypeNameHandling values other than None", - Justification = "In-proc test-only emulator; serialized bytes never cross a trust boundary. See inline CodeQL suppression comment above.")] - [SuppressMessage( - "Security", - "CA2327:Do not use insecure deserializer settings", - Justification = "In-proc test-only emulator; serialized bytes never cross a trust boundary. See inline CodeQL suppression comment above.")] + // CodeQL [SM02211] False positive: in-proc test-only emulator; bytes stay in-memory and never cross a trust boundary. static readonly JsonSerializerSettings StateJsonSettings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto }; ///