SIGN IN SIGN UP
appsmithorg / appsmith UNCLAIMED

Platform to build admin panels, internal tools, and dashboards. Integrates with 25+ databases and any API.

0 0 68 TypeScript

fix(security): Appsmith App Viewer datasource configuration leak via import helper (GHSA-93mf-9h52-gfxp) (#41764)

## Summary

fix(security): Appsmith App Viewer datasource configuration leak via
import helper (GHSA-93mf-9h52-gfxp)

- **Primary fix:**
`DatasourceImportableServiceCEImpl.getEntitiesPresentInWorkspace()` was
calling `getAllByWorkspaceIdWithStorages(workspaceId, null)` — passing
`null` as the ACL permission, which bypasses authorization entirely.
Changed to enforce `datasourcePermission.getReadPermission()`
(`READ_DATASOURCES`), consistent with the standard datasource listing
endpoint.
- **Constructor update:** Injected `DatasourcePermission` into both
`DatasourceImportableServiceCEImpl` and
`DatasourceImportableServiceImpl` constructors (Spring auto-wires the
bean).
- **Test coverage:** Added a regression test
(`should_enforceReadPermission_when_getEntitiesPresentInWorkspace_isCalled`)
annotated with GHSA ID, verifying that `READ_DATASOURCES` permission is
always passed and `null` is never used.

## Vulnerability

| Field | Value |
|-------|-------|
| **GHSA** |
[GHSA-93mf-9h52-gfxp](https://github.com/appsmithorg/appsmith/security/advisories/GHSA-93mf-9h52-gfxp)
|
| **CVSS** | 7.7 (high) |
| **CWE** | CWE-200, CWE-862 |
| **Affected component** |
`DatasourceImportableServiceCEImpl.getEntitiesPresentInWorkspace()` |

## Exposure Analysis

- **Who can exploit this:** Any authenticated user with `App Viewer`
access to a workspace. This is the lowest privilege role — no admin,
developer, or owner access required.
- **What an attacker can achieve:** Full read access to datasource
configuration for all datasources in the workspace, including internal
URLs, custom headers (e.g., `Authorization: Bearer <token>`), custom
properties (e.g., API keys), and connection metadata. This is a
confidentiality breach of backend infrastructure credentials.
- **Evidence of exploitation:** No evidence of exploitation in the wild.
Discovered via security advisory report.
- **Blast radius:** All datasources in the target workspace are exposed.
The attack is per-workspace — an App Viewer in workspace A cannot access
workspace B's datasources. However, within a workspace, ALL datasource
secrets are leaked regardless of which application they belong to.

## Fix

- **Root cause:**
`DatasourceImportableServiceCEImpl.getEntitiesPresentInWorkspace()`
(line 602) called
`datasourceService.getAllByWorkspaceIdWithStorages(workspaceId, null)`.
When `AclPermission` is `null`, the MongoDB repository layer skips ACL
filtering and returns all matching documents, bypassing the policy-based
permission model.
- **Fix strategy:** Inject `DatasourcePermission` into the service and
replace `null` with `datasourcePermission.getReadPermission()`
(`AclPermission.READ_DATASOURCES`). This is the same permission used by
the standard `GET /api/v1/datasources?workspaceId=` endpoint —
consistent, minimal, and at the correct layer.
- **Intentionally NOT changed:** (1) `importEntities()` in the same
class (line 117) also uses `null` permission — this is intentional
because the import pipeline has its own authorization layer (edit
permission on existing datasources, create permission on workspace). (2)
`DatasourceForkableServiceCEImpl.getExistingEntitiesInTarget()` also
uses `null` — fork operations require higher-level permissions upstream.
- **Defense-in-depth:** The fix is at the data-access layer, which is
the correct boundary. All callers of `getEntitiesPresentInWorkspace()`
automatically inherit the permission enforcement.

## Test plan

- [x] Failing test for the exploit scenario passes after fix
- [x] All existing tests in affected modules pass (no regressions) — 9/9
tests green
- [x] Codebase audit: grepped for
`getAllByWorkspaceIdWithStorages.*null` — remaining instances are in
authorized internal pipelines
- [x] Compilation clean (`mvn compile -DskipTests`)
- [ ] Manual reproduction of advisory PoC confirms the fix

## CE/EE sync

CE-only safe: the modified files
(`DatasourceImportableServiceCEImpl.java`,
`DatasourceImportableServiceImpl.java`) are CE files that EE inherits.
The hourly CE→EE sync will propagate the fix. The EE repo already has
identical changes as uncommitted modifications, confirming alignment.

## Disclosure

> **Do not merge until advisory is ready for disclosure coordination.**
>
> After merge:
> 1. Confirm fix is in release branch
> 2. Coordinate with security team on disclosure timeline
> 3. Update advisory with patched version and publish
> 4. Notify reporter

## Follow-ups

- No additional vulnerable locations found during codebase audit — no
follow-up PRs needed.
- Linear ticket:
[APP-15189](https://linear.app/appsmith/issue/APP-15189)


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Bug Fixes**
* Datasource listings now respect computed read permissions so users
only see workspace datasources they are allowed to access.

* **Tests**
* Added tests validating read-permission enforcement for datasource
visibility to prevent unauthorized exposure.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->


## Automation

/ok-to-test tags="@tag.All"

<!-- This is an auto-generated comment: Cypress test results  -->
> [!TIP]
> 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉
> Workflow run:
<https://github.com/appsmithorg/appsmith/actions/runs/24981307163>
> Commit: 54b3c7fb763f50c3d25ed09c34859cbfe562b68c
> <a
href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=24981307163&attempt=1"
target="_blank">Cypress dashboard</a>.
> Tags: `@tag.All`
> Spec:
> <hr>Mon, 27 Apr 2026 08:09:14 UTC
<!-- end of auto-generated comment: Cypress test results  -->
S
subratadeypappu committed
a92dee41fe82ad5fc4f4166df86ab423a1f93bd9
Parent: 99d6918
Committed by GitHub <noreply@github.com> on 4/27/2026, 2:10:36 PM