{"record":{"id":"6f46c8bac9ebba2f","repo":"SonarSource/sonarqube","slug":"insufficient-privileges-6f46c8","errorCode":null,"errorMessage":"Insufficient privileges","messagePattern":"Insufficient privileges","errorType":"exception","errorClass":"ForbiddenException","httpStatus":403,"severity":"error","filePath":"server/sonar-webserver-webapi/src/main/java/org/sonar/server/ui/ws/ComponentAction.java","lineNumber":161,"sourceCode":"      .setExampleValue(KEY_PULL_REQUEST_EXAMPLE_001);\n  }\n\n  @Override\n  public void handle(Request request, Response response) throws Exception {\n    String componentKey = request.mandatoryParam(PARAM_COMPONENT);\n    try (DbSession session = dbClient.openSession(false)) {\n      String branch = request.param(PARAM_BRANCH);\n      String pullRequest = request.param(PARAM_PULL_REQUEST);\n      ComponentDto component = componentFinder.getByKeyAndOptionalBranchOrPullRequest(session, componentKey, branch, pullRequest);\n      checkComponentNotAModuleAndNotADirectory(component);\n      ComponentDto rootComponent = getRootProjectOrBranch(component, session);\n      // will be empty for portfolios\n      Optional<BranchDto> branchDto = dbClient.branchDao().selectByUuid(session, rootComponent.branchUuid());\n      String projectOrPortfolioUuid = branchDto.map(BranchDto::getProjectUuid).orElse(rootComponent.branchUuid());\n      if (!userSession.hasComponentPermission(USER, component) &&\n        !userSession.hasComponentPermission(ADMIN, component) &&\n        !userSession.isSystemAdministrator()) {\n        throw insufficientPrivilegesException();\n      }\n      Optional<SnapshotDto> analysis = dbClient.snapshotDao().selectLastAnalysisByRootComponentUuid(session, component.branchUuid());\n\n      try (JsonWriter json = response.newJsonWriter()) {\n        json.beginObject();\n        boolean isFavourite = isFavourite(session, projectOrPortfolioUuid, component);\n        writeComponent(json, component, analysis.orElse(null), isFavourite, branchDto.map(BranchDto::getBranchKey).orElse(null));\n        writeProfiles(json, session, component);\n        writeQualityGate(json, session, projectOrPortfolioUuid);\n        if (userSession.hasComponentPermission(ADMIN, component) ||\n          userSession.hasComponentPermission(ARCHITECTURE_ADMIN, component) ||\n          userSession.hasPermission(ADMINISTER_QUALITY_PROFILES) ||\n          userSession.hasPermission(ADMINISTER_QUALITY_GATES)) {\n          writeConfiguration(json, component);\n        }\n        writeBreadCrumbs(json, session, component);\n        json.endObject().close();\n      }","sourceCodeStart":143,"sourceCodeEnd":179,"githubUrl":"https://github.com/SonarSource/sonarqube/blob/184c821202192afc1c599fc912d0889b69fffa53/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ui/ws/ComponentAction.java#L143-L179","documentation":"The SonarQube Web API component navigation action ('api/navigation/component' / component tree root detail) requires the caller to hold USER or ADMIN permission on the component, or be a system administrator. When the user session has none of these, the handler throws the insufficient-privileges exception instead of returning component data, preventing information disclosure about projects the caller cannot access.","triggerScenarios":"Requesting the component navigation endpoint for a root component where the logged-in user has neither Browse (USER) nor Administer (ADMIN) component permission and is not a system administrator.","commonSituations":"Frontend navigation stale after permissions changed; shared bookmarks/URLs to a component the viewer cannot see; third-party dashboards calling the navigation API with a limited-service account.","solutions":["Grant the user Browse (USER) permission on the component/project: Project Settings > Permissions.","Grant ADMIN permission only if administration data is actually needed.","Use a system administrator account for admin-level navigation queries.","Update the client to handle a 403 gracefully and prompt the user to request access."],"exampleFix":"// before\ncurl -u limitedUser: http://sonar/api/navigation/component?component=uuid-of-project\n\n// after: grant Browse permission to limitedUser on the project\ncurl -u limitedUser: http://sonar/api/navigation/component?component=uuid-of-project","handlingStrategy":"try-catch","validationCode":"// Pre-check via the WS client before navigation call:\n// GET /api/components/show?component=<key> will 403 for unauthorized users too;\n// better: GET /api/projects/search and verify the component key is visible to the user.","typeGuard":null,"tryCatchPattern":"try {\n  ComponentWsResponse r = wsClient.navigationComponent().execute();\n} catch (SonarQubeClientException e) { // or check response.code()==403\n  if (e.status() == 403) {\n    ui.showAccessDenied(\"You do not have permission to view this component\");\n  } else throw e;\n}","preventionTips":["Grant Browse permission to the groups/users that legitimately navigate to the project.","Avoid sharing component URLs across users with different permission sets.","Check permissions reactively in the UI after permission changes.","Use system administrator accounts only for admin diagnostics."],"tags":["sonarqube","webapi","authorization","permissions"],"backgroundTag":"insufficient-permissions","analyzedSha":"184c821202192afc1c599fc912d0889b69fffa53","analyzedAt":"2026-09-09T12:23:51.573Z","contentChangedAt":"2026-09-09T12:23:51.573Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}