From 0ab93ccc5eae782d1e9d0e6abfe558adfea01843 Mon Sep 17 00:00:00 2001 From: Anatoli Beliaev Date: Thu, 30 Apr 2026 23:02:30 -0700 Subject: [PATCH 1/3] Add CodeQL suppressions for serialization security warnings in PutJsonAsync method Co-authored-by: Copilot --- .../Remote/RemoteOrchestrationServiceClient.cs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/DurableTask.AzureServiceFabric/Remote/RemoteOrchestrationServiceClient.cs b/src/DurableTask.AzureServiceFabric/Remote/RemoteOrchestrationServiceClient.cs index 2143dd414..b27fe71d6 100644 --- a/src/DurableTask.AzureServiceFabric/Remote/RemoteOrchestrationServiceClient.cs +++ b/src/DurableTask.AzureServiceFabric/Remote/RemoteOrchestrationServiceClient.cs @@ -15,6 +15,7 @@ namespace DurableTask.AzureServiceFabric.Remote { using System; using System.Collections.Generic; + using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Net; using System.Net.Http; @@ -301,8 +302,23 @@ private async Task GetStringResponseAsync(string instanceId, string frag } } + [SuppressMessage( + "Security", + "CA2326:Do not use TypeNameHandling values other than None", + Justification = "Serialization (write) path only; no untrusted JSON is deserialized through these settings. See inline CodeQL suppression comment below.")] + [SuppressMessage( + "Security", + "CA2327:Do not use insecure deserializer settings", + Justification = "Serialization (write) path only; no untrusted JSON is deserialized through these settings. See inline CodeQL suppression comment below.")] private async Task PutJsonAsync(string instanceId, string fragment, object @object, CancellationToken cancellationToken) { + // CodeQL [SM02211] False positive on the serialization (write) path. + // JsonMediaTypeFormatter is only used here to serialize outgoing PUT request bodies; + // no untrusted JSON is deserialized through these settings. The matching response + // reads use the default formatter (TypeNameHandling.None) or strongly-typed + // ReadAsAsync. The wire format requires TypeNameHandling.All for interop with + // FabricOrchestrationServiceController, which is configured symmetrically in + // Service/Startup.cs. var mediaFormatter = new JsonMediaTypeFormatter() { SerializerSettings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All } From 6c6ab0bf504c362b8a54f872de354c413c786596 Mon Sep 17 00:00:00 2001 From: Anatoli Beliaev Date: Fri, 1 May 2026 11:39:25 -0700 Subject: [PATCH 2/3] Fix suppression syntax Co-authored-by: Copilot --- .../Remote/RemoteOrchestrationServiceClient.cs | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/src/DurableTask.AzureServiceFabric/Remote/RemoteOrchestrationServiceClient.cs b/src/DurableTask.AzureServiceFabric/Remote/RemoteOrchestrationServiceClient.cs index b27fe71d6..2741a9ef3 100644 --- a/src/DurableTask.AzureServiceFabric/Remote/RemoteOrchestrationServiceClient.cs +++ b/src/DurableTask.AzureServiceFabric/Remote/RemoteOrchestrationServiceClient.cs @@ -15,7 +15,6 @@ namespace DurableTask.AzureServiceFabric.Remote { using System; using System.Collections.Generic; - using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Net; using System.Net.Http; @@ -302,23 +301,9 @@ private async Task GetStringResponseAsync(string instanceId, string frag } } - [SuppressMessage( - "Security", - "CA2326:Do not use TypeNameHandling values other than None", - Justification = "Serialization (write) path only; no untrusted JSON is deserialized through these settings. See inline CodeQL suppression comment below.")] - [SuppressMessage( - "Security", - "CA2327:Do not use insecure deserializer settings", - Justification = "Serialization (write) path only; no untrusted JSON is deserialized through these settings. See inline CodeQL suppression comment below.")] + // CodeQL [SM02211] False positive: serialization (write) path only; no untrusted JSON is deserialized here. private async Task PutJsonAsync(string instanceId, string fragment, object @object, CancellationToken cancellationToken) { - // CodeQL [SM02211] False positive on the serialization (write) path. - // JsonMediaTypeFormatter is only used here to serialize outgoing PUT request bodies; - // no untrusted JSON is deserialized through these settings. The matching response - // reads use the default formatter (TypeNameHandling.None) or strongly-typed - // ReadAsAsync. The wire format requires TypeNameHandling.All for interop with - // FabricOrchestrationServiceController, which is configured symmetrically in - // Service/Startup.cs. var mediaFormatter = new JsonMediaTypeFormatter() { SerializerSettings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All } From 52430cb9dcf41d23f561802a177a3ab586b3b34a Mon Sep 17 00:00:00 2001 From: Anatoli Beliaev Date: Fri, 1 May 2026 12:30:12 -0700 Subject: [PATCH 3/3] Move suppression comment to the correct line Co-authored-by: Copilot --- .../Remote/RemoteOrchestrationServiceClient.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DurableTask.AzureServiceFabric/Remote/RemoteOrchestrationServiceClient.cs b/src/DurableTask.AzureServiceFabric/Remote/RemoteOrchestrationServiceClient.cs index 2741a9ef3..5f45cb752 100644 --- a/src/DurableTask.AzureServiceFabric/Remote/RemoteOrchestrationServiceClient.cs +++ b/src/DurableTask.AzureServiceFabric/Remote/RemoteOrchestrationServiceClient.cs @@ -301,11 +301,11 @@ private async Task GetStringResponseAsync(string instanceId, string frag } } - // CodeQL [SM02211] False positive: serialization (write) path only; no untrusted JSON is deserialized here. private async Task PutJsonAsync(string instanceId, string fragment, object @object, CancellationToken cancellationToken) { var mediaFormatter = new JsonMediaTypeFormatter() { + // CodeQL [SM02211] False positive: serialization (write) path only; no untrusted JSON is deserialized here. SerializerSettings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All } };