From 618fcf664d6769e8a4bb01a4468b517b57606d09 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 13 May 2026 13:17:25 +0000 Subject: [PATCH 1/2] fix(security): remove ex.Message leak in canvas jsonlPath error response PR #294 sanitised the main canvas command handlers (navigate, eval, snapshot, a2ui) but left one ex.Message leak at the jsonlPath read path: Error($"Failed to read jsonlPath: {ex.Message}"). The exception detail was already written to the local logger on the line above, so diagnostic fidelity is preserved; only the gateway-bound error string is stripped. Closes: the residual canvas capability gap identified post-#294. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/OpenClaw.Shared/Capabilities/CanvasCapability.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenClaw.Shared/Capabilities/CanvasCapability.cs b/src/OpenClaw.Shared/Capabilities/CanvasCapability.cs index 8b9c02458..7999bafce 100644 --- a/src/OpenClaw.Shared/Capabilities/CanvasCapability.cs +++ b/src/OpenClaw.Shared/Capabilities/CanvasCapability.cs @@ -298,7 +298,7 @@ private NodeInvokeResponse HandleA2UIPush(NodeInvokeRequest request) catch (Exception ex) { Logger.Error($"{request.Command}: failed to read jsonlPath", ex); - return Error($"Failed to read jsonlPath: {ex.Message}"); + return Error("Failed to read jsonlPath"); } } From ab75d4466c156b064a5767a8b591cd8f1f7b108c Mon Sep 17 00:00:00 2001 From: Scott Hanselman Date: Wed, 13 May 2026 18:56:39 -0700 Subject: [PATCH 2/2] Update canvas jsonlPath security tests Assert sanitized jsonlPath error responses now that internal exception details stay local to logs. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- tests/OpenClaw.Shared.Tests/A2UICapabilitySecurityTests.cs | 4 ++-- tests/OpenClaw.Shared.Tests/CapabilityTests.cs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/OpenClaw.Shared.Tests/A2UICapabilitySecurityTests.cs b/tests/OpenClaw.Shared.Tests/A2UICapabilitySecurityTests.cs index a435677b8..4438f41e2 100644 --- a/tests/OpenClaw.Shared.Tests/A2UICapabilitySecurityTests.cs +++ b/tests/OpenClaw.Shared.Tests/A2UICapabilitySecurityTests.cs @@ -74,7 +74,7 @@ public async Task A2UIPush_FileJsonl_OverCap_ReturnsError() }; var res = await cap.ExecuteAsync(req); Assert.False(res.Ok); - Assert.Contains("maximum size", res.Error); + Assert.Equal("Failed to read jsonlPath", res.Error); } finally { @@ -125,7 +125,7 @@ public async Task A2UIPush_FileJsonl_SymlinkOutsideTemp_ReturnsError() var res = await cap.ExecuteAsync(req); Assert.False(res.Ok); - Assert.Contains("temp", res.Error, StringComparison.OrdinalIgnoreCase); + Assert.Equal("Failed to read jsonlPath", res.Error); } finally { diff --git a/tests/OpenClaw.Shared.Tests/CapabilityTests.cs b/tests/OpenClaw.Shared.Tests/CapabilityTests.cs index 8b75c1fb5..f5fb14925 100644 --- a/tests/OpenClaw.Shared.Tests/CapabilityTests.cs +++ b/tests/OpenClaw.Shared.Tests/CapabilityTests.cs @@ -1489,7 +1489,7 @@ public async Task A2UIPush_WithJsonlPathOutsideTempDir_ReturnsError() }; var res = await cap.ExecuteAsync(req); Assert.False(res.Ok); - Assert.Contains("temp directory", res.Error); + Assert.Equal("Failed to read jsonlPath", res.Error); } [Fact] @@ -1506,7 +1506,7 @@ public async Task A2UIPush_WithJsonlPathTraversal_ReturnsError() }; var res = await cap.ExecuteAsync(req); Assert.False(res.Ok); - Assert.Contains("temp directory", res.Error); + Assert.Equal("Failed to read jsonlPath", res.Error); } [Fact]