From ee30de38fc0ad88c1a3fadb99637e946eb048388 Mon Sep 17 00:00:00 2001 From: sakith03 Date: Sun, 19 Apr 2026 20:23:26 +0530 Subject: [PATCH 1/3] fixed broken access control on observability REST APIs (IDOR) --- icp_server/observability_service.bal | 31 ++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/icp_server/observability_service.bal b/icp_server/observability_service.bal index a6fe3fe1c..06a61eaec 100644 --- a/icp_server/observability_service.bal +++ b/icp_server/observability_service.bal @@ -14,6 +14,7 @@ // specific language governing permissions and limitations // under the License. +import icp_server.auth; import icp_server.storage as storage; import icp_server.types as types; @@ -121,6 +122,30 @@ isolated function initObservabilityClient() returns http:Client? { return httpClient; } +// Caller must run after HTTP JWT validation (Authorization present and signature verified). +isolated function extractUserFromObservabilityRequest(http:Request request) returns types:UserContextV2|error { + string|http:HeaderNotFoundError authHeader = request.getHeader("Authorization"); + if authHeader is http:HeaderNotFoundError { + return error("Authorization header missing"); + } + return auth:extractUserContextV2(authHeader); +} + +// Restrict resolved runtimes to those the user may access (integration + environment scope). +isolated function filterRuntimeIdsForUser(string userId, string[] runtimeIds) returns string[]|error { + string[] filtered = []; + foreach string rid in runtimeIds { + boolean|error allowed = storage:hasAccessToRuntime(userId, rid); + if allowed is error { + return allowed; + } + if allowed { + filtered.push(rid); + } + } + return filtered; +} + @http:ServiceConfig { auth: [ { @@ -155,6 +180,9 @@ service /icp/observability on httpListener { environmentList: logRequest.environmentList }); + types:UserContextV2 userContext = check extractUserFromObservabilityRequest(request); + runtimeIdList = check filterRuntimeIdsForUser(userContext.userId, runtimeIdList); + // If component/environment filters were provided but no runtimes found, return empty result boolean hasFilters = logRequest.componentId is string || (logRequest.componentIdList is string[] && (logRequest.componentIdList).length() > 0) || @@ -238,6 +266,9 @@ service /icp/observability on httpListener { environmentList: metricRequest.environmentList }); + types:UserContextV2 userContext = check extractUserFromObservabilityRequest(request); + runtimeIdList = check filterRuntimeIdsForUser(userContext.userId, runtimeIdList); + // If component/environment filters were provided but no runtimes found, return empty result boolean hasFilters = metricRequest.componentId is string || (metricRequest.componentIdList is string[] && (metricRequest.componentIdList).length() > 0) || From d0129c019f7e9b8e27cf72901fc582b715394671 Mon Sep 17 00:00:00 2001 From: Sakith Abeywickrama <161790795+sakith03@users.noreply.github.com> Date: Sun, 19 Apr 2026 20:42:25 +0530 Subject: [PATCH 2/3] Update icp_server/observability_service.bal Co-authored-by: wso2-engineering[bot] <229087779+wso2-engineering[bot]@users.noreply.github.com> --- icp_server/observability_service.bal | 1 + 1 file changed, 1 insertion(+) diff --git a/icp_server/observability_service.bal b/icp_server/observability_service.bal index 06a61eaec..ca2e8b085 100644 --- a/icp_server/observability_service.bal +++ b/icp_server/observability_service.bal @@ -133,6 +133,7 @@ isolated function extractUserFromObservabilityRequest(http:Request request) retu // Restrict resolved runtimes to those the user may access (integration + environment scope). isolated function filterRuntimeIdsForUser(string userId, string[] runtimeIds) returns string[]|error { + log:printDebug("Filtering runtime IDs for user", userId = userId, runtimeCount = runtimeIds.length()); string[] filtered = []; foreach string rid in runtimeIds { boolean|error allowed = storage:hasAccessToRuntime(userId, rid); From 8fd4aebc0c1fad26ede965df21e70d71a2bc1f17 Mon Sep 17 00:00:00 2001 From: Sakith Abeywickrama <161790795+sakith03@users.noreply.github.com> Date: Sun, 19 Apr 2026 20:42:34 +0530 Subject: [PATCH 3/3] Update icp_server/observability_service.bal Co-authored-by: wso2-engineering[bot] <229087779+wso2-engineering[bot]@users.noreply.github.com> --- icp_server/observability_service.bal | 1 + 1 file changed, 1 insertion(+) diff --git a/icp_server/observability_service.bal b/icp_server/observability_service.bal index ca2e8b085..7e43e0e27 100644 --- a/icp_server/observability_service.bal +++ b/icp_server/observability_service.bal @@ -182,6 +182,7 @@ service /icp/observability on httpListener { }); types:UserContextV2 userContext = check extractUserFromObservabilityRequest(request); + log:printInfo("Processing logs request", userId = userContext.userId); runtimeIdList = check filterRuntimeIdsForUser(userContext.userId, runtimeIdList); // If component/environment filters were provided but no runtimes found, return empty result