Skip to content

Cross-org IDOR: /api/datasources/{id}/structure missing per-object authorization #2199

Open

Description

@HieuPenguinnn

Summary

GET /api/datasources/{datasourceId}/structure has no per object authorization, so any authenticated user can read the full database schema of a data source owned by another organization, and with ignoreCache=true force a live connection that uses the owner's stored credentials.

Root cause

DatasourceController.getStructure calls the structure service directly with no permission check, while every sibling single data source route gates on checkCurrentUserManageDatasourcePermission.

server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/datasource/DatasourceController.java (around line 113):

public Mono<ResponseView<DatasourceStructure>> getStructure(@PathVariable String datasourceId, ...) {
    return ... datasourceStructureService.getStructure(objectId, ignoreCache) ...; // no permission check
}

Contrast getById (around line 63) which routes through datasourceApiService.findByIdWithPermission, and update/delete which check permission. The structure service does not re compute authorization either:

lowcoder-domain/.../datasource/service/impl/DatasourceStructureServiceImpl.java:

private Mono<DatasourceStructure> getLatestAndSave(String datasourceId) {
    return datasourceService.getById(datasourceId) // no organization or permission filter
        ...
}

DatasourceServiceImpl.getById is a plain repository.findById, and the route sits under the blanket /api/** to .authenticated() rule, so any logged in member of any organization reaches it.

Impact

Cross organization disclosure of another org's database schema (tables, columns, types, keys), and with ignoreCache=true a live connection to the owner's database using the owner's stored credentials. CWE-639, CWE-862.

Fix

Apply the same checkCurrentUserManageDatasourcePermission (or an equivalent org scoped permission check) to getStructure before resolving the data source, as the sibling routes do.

Write-up

Full analysis with the pinned source trace at tag 2.7.6: https://hackmd.io/@hieund/lowcoder-datasource-structure-cross-org-idor

Reported by hieuPenguinnn (github.com/hieuPenguinnn). Static source review only, no live instance was contacted.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions