Sanitize MCP errors to avoid leaking internal details
Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
This commit is contained in:
@@ -92,4 +92,27 @@ func TestMCP_Asset_CRUD(t *testing.T) {
|
||||
"id": addResult.Asset.ID,
|
||||
}, &deleteResult)
|
||||
assert.Equal(t, addResult.Asset.ID, deleteResult.DeletedAssetID)
|
||||
|
||||
// Get deleted asset returns sanitized not-found error
|
||||
msg := mc.CallToolExpectToolError("getAsset", map[string]any{
|
||||
"id": addResult.Asset.ID,
|
||||
})
|
||||
assert.Equal(t, "resource not found", msg)
|
||||
}
|
||||
|
||||
func TestMCP_Asset_PermissionDenied(t *testing.T) {
|
||||
t.Parallel()
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
orgID := owner.GetOrganizationID().String()
|
||||
viewer := testutil.NewClientInOrg(t, testutil.RoleViewer, owner)
|
||||
viewerMC := testutil.NewMCPClient(t, viewer)
|
||||
|
||||
msg := viewerMC.CallToolExpectToolError("addAsset", map[string]any{
|
||||
"organizationId": orgID,
|
||||
"name": factory.SafeName("Asset"),
|
||||
"amount": 1,
|
||||
"assetType": "VIRTUAL",
|
||||
"dataTypesStored": "PII",
|
||||
})
|
||||
assert.Contains(t, msg, "permission denied")
|
||||
}
|
||||
|
||||
@@ -86,4 +86,24 @@ func TestMCP_Risk_CRUD(t *testing.T) {
|
||||
"id": addResult.Risk.ID,
|
||||
}, &deleteResult)
|
||||
assert.Equal(t, addResult.Risk.ID, deleteResult.DeletedRiskID)
|
||||
|
||||
// Get deleted risk returns sanitized not-found error
|
||||
msg := mc.CallToolExpectToolError("getRisk", map[string]any{
|
||||
"id": addResult.Risk.ID,
|
||||
})
|
||||
assert.Equal(t, "resource not found", msg)
|
||||
}
|
||||
|
||||
func TestMCP_Risk_PermissionDenied(t *testing.T) {
|
||||
t.Parallel()
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
orgID := owner.GetOrganizationID().String()
|
||||
viewer := testutil.NewClientInOrg(t, testutil.RoleViewer, owner)
|
||||
viewerMC := testutil.NewMCPClient(t, viewer)
|
||||
|
||||
msg := viewerMC.CallToolExpectToolError("addRisk", map[string]any{
|
||||
"organizationId": orgID,
|
||||
"name": factory.SafeName("Risk"),
|
||||
})
|
||||
assert.Contains(t, msg, "permission denied")
|
||||
}
|
||||
|
||||
@@ -76,4 +76,42 @@ func TestMCP_Vendor_CRUD(t *testing.T) {
|
||||
"id": addResult.Vendor.ID,
|
||||
}, &deleteResult)
|
||||
assert.Equal(t, addResult.Vendor.ID, deleteResult.DeletedVendorID)
|
||||
|
||||
// Update deleted vendor returns sanitized not-found error
|
||||
msg := mc.CallToolExpectToolError("updateVendor", map[string]any{
|
||||
"id": addResult.Vendor.ID,
|
||||
"name": "Should Fail",
|
||||
})
|
||||
assert.Equal(t, "resource not found", msg)
|
||||
}
|
||||
|
||||
func TestMCP_Vendor_ValidationError(t *testing.T) {
|
||||
t.Parallel()
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
mc := testutil.NewMCPClient(t, owner)
|
||||
orgID := owner.GetOrganizationID().String()
|
||||
|
||||
msg := mc.CallToolExpectToolError("addVendor", map[string]any{
|
||||
"organizationId": orgID,
|
||||
"name": "",
|
||||
})
|
||||
assert.Contains(t, msg, "name")
|
||||
assert.NotContains(t, msg, "pq:")
|
||||
assert.NotContains(t, msg, "sql:")
|
||||
}
|
||||
|
||||
func TestMCP_Vendor_PermissionDenied(t *testing.T) {
|
||||
t.Parallel()
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
orgID := owner.GetOrganizationID().String()
|
||||
viewer := testutil.NewClientInOrg(t, testutil.RoleViewer, owner)
|
||||
viewerMC := testutil.NewMCPClient(t, viewer)
|
||||
|
||||
msg := viewerMC.CallToolExpectToolError("addVendor", map[string]any{
|
||||
"organizationId": orgID,
|
||||
"name": factory.SafeName("Vendor"),
|
||||
})
|
||||
assert.Contains(t, msg, "permission denied")
|
||||
assert.NotContains(t, msg, "pq:")
|
||||
assert.NotContains(t, msg, "sql:")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user