fix(security): stop leaking capability exception messages (#291)
Sanitizes node capability error responses while preserving details in local logs and updates tests for generic responses.\n\nValidation: local ARM64 build passed; Shared tests 1296 passed / 20 skipped; Tray tests 466 passed; remote CI green.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
parent
43873c1005
commit
ad120cdf70
@ -60,7 +60,7 @@ public class CameraCapability : NodeCapabilityBase
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error("Camera list failed", ex);
|
||||
return Error($"List failed: {ex.Message}");
|
||||
return Error("List failed");
|
||||
}
|
||||
}
|
||||
|
||||
@ -106,7 +106,7 @@ public class CameraCapability : NodeCapabilityBase
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error("Camera snap failed", ex);
|
||||
return Error($"Snap failed: {ex.Message}");
|
||||
return Error("Snap failed");
|
||||
}
|
||||
}
|
||||
|
||||
@ -147,7 +147,7 @@ public class CameraCapability : NodeCapabilityBase
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error("Camera clip failed", ex);
|
||||
return Error($"Clip failed: {ex.Message}");
|
||||
return Error("Clip failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -64,7 +64,7 @@ public class LocationCapability : NodeCapabilityBase
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error("location.get failed", ex);
|
||||
return Error($"Location failed: {ex.Message}");
|
||||
return Error("Location failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -84,7 +84,7 @@ public class ScreenCapability : NodeCapabilityBase
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error("Screen capture failed", ex);
|
||||
return Error($"Capture failed: {ex.Message}");
|
||||
return Error("Capture failed");
|
||||
}
|
||||
}
|
||||
|
||||
@ -134,7 +134,7 @@ public class ScreenCapability : NodeCapabilityBase
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error("Screen recording failed", ex);
|
||||
return Error($"Recording failed: {ex.Message}");
|
||||
return Error("Recording failed");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -271,7 +271,7 @@ public class SystemCapability : NodeCapabilityBase
|
||||
{
|
||||
// Rail 1: no silent fallback — handler exceptions become typed denies.
|
||||
Logger.Error($"[system.run] corr={correlationId} path=v2 handler threw", ex);
|
||||
v2Result = ExecApprovalV2Result.ValidationFailed($"Handler exception: {ex.Message}");
|
||||
v2Result = ExecApprovalV2Result.ValidationFailed("Handler exception");
|
||||
}
|
||||
|
||||
Logger.Info($"[system.run] corr={correlationId} decision={v2Result.Code} reason={v2Result.Reason}");
|
||||
@ -413,7 +413,7 @@ public class SystemCapability : NodeCapabilityBase
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error("system.run failed", ex);
|
||||
return Error($"Execution failed: {ex.Message}");
|
||||
return Error("Execution failed");
|
||||
}
|
||||
}
|
||||
|
||||
@ -614,7 +614,7 @@ public class SystemCapability : NodeCapabilityBase
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error("execApprovals.set failed", ex);
|
||||
return Error($"Failed to update policy: {ex.Message}");
|
||||
return Error("Failed to update policy");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -2082,7 +2082,7 @@ public class ScreenCapabilityTests
|
||||
var req = new NodeInvokeRequest { Id = "s5", Command = "screen.snapshot", Args = Parse("""{}""") };
|
||||
var res = await cap.ExecuteAsync(req);
|
||||
Assert.False(res.Ok);
|
||||
Assert.Contains("Display access denied", res.Error);
|
||||
Assert.Equal("Capture failed", res.Error);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@ -2327,7 +2327,7 @@ public class ScreenCapabilityTests
|
||||
var req = new NodeInvokeRequest { Id = "s15", Command = "screen.record", Args = Parse("""{}""") };
|
||||
var res = await cap.ExecuteAsync(req);
|
||||
Assert.False(res.Ok);
|
||||
Assert.Contains("Capture permission denied", res.Error);
|
||||
Assert.Equal("Recording failed", res.Error);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2457,7 +2457,7 @@ public class CameraCapabilityTests
|
||||
var req = new NodeInvokeRequest { Id = "cam6", Command = "camera.snap", Args = Parse("""{}""") };
|
||||
var res = await cap.ExecuteAsync(req);
|
||||
Assert.False(res.Ok);
|
||||
Assert.Contains("Camera access blocked", res.Error);
|
||||
Assert.Equal("Snap failed", res.Error);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@ -2892,7 +2892,7 @@ public class LocationCapabilityTests
|
||||
var req = new NodeInvokeRequest { Id = "loc6", Command = "location.get", Args = Parse("""{}""") };
|
||||
var res = await cap.ExecuteAsync(req);
|
||||
Assert.False(res.Ok);
|
||||
Assert.Contains("GPS unavailable", res.Error);
|
||||
Assert.Equal("Location failed", res.Error);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
||||
Loading…
Reference in New Issue
Block a user