# Uncovering a hidden BOLA in Appsmith's snapshot logic

Appsmith's snapshot delete endpoint skipped object-level authorization, letting any authenticated user delete another tenant's application snapshots by applicationId.

- Payout: Research
- Severity: medium
- Program: Appsmith
- Write-up by: Strix
- Disclosed: 2026-04-12
- Write-up quality: 6/10
- Original: https://www.strix.ai/blog/where-others-missed-it-appsmith-bola
- Library page: https://bugbountylibrary.com/r/blog%3Astrix-ai-blog-where-others-missed-it-appsmith-bola
- Tags: area:web domain:api domain:web impact:dos impact:integrity kind:research platform:research sev:medium tech:java technique:source-review vuln:access-control vuln:idor

**Target:** REST API endpoint DELETE /api/v1/applications/snapshot/{applicationId}
**Root cause:** ApplicationSnapshotServiceCEImpl.deleteSnapshot called applicationSnapshotRepository.deleteAllByApplicationId() directly without resolving the application via applicationService.findById(..., getEditPermission()), unlike the restore path.
**Steps:**
1. As User A, create snapshot: `POST /api/v1/applications/snapshot/<APP_ID>` with header `X-Requested-By: Appsmith`
2. Confirm snapshot exists via `GET /api/v1/applications/snapshot/<APP_ID>` (updatedTime non-null)
3. As User B, confirm no access: `POST /api/v1/applications/snapshot/<APP_ID>` and `GET /api/v1/applications/export/<APP_ID>` return 404
4. As User B, send `DELETE /api/v1/applications/snapshot/<APP_ID>` with `X-Requested-By: Appsmith`
5. Observe 200 with data: true; re-check metadata shows updatedTime: null
**How found:** Code review of backend logic: compared the delete path against restoreSnapshot, which correctly called applicationService.findById with getEditPermission(); the delete path skipped that check entirely and went straight to deleteAllByApplicationId.
**Exploitation:** Any authenticated user scrapes a victim applicationId from public app HTML source or API traffic, then issues DELETE on the snapshot endpoint with their own session cookies; the server deletes all snapshots for that application without checking ownership.
**Insight:** When auditing multi-tenant apps, diff sibling CRUD handlers on the same resource: if restore/export enforce findById with a permission, check whether delete/create do the same — the missing check is usually in the one handler that never resolves the object.

