-
-
Notifications
You must be signed in to change notification settings - Fork 355
Description
Summary
Multiple authorization and IDOR (Insecure Direct Object Reference) vulnerabilities were found across the Peppermint API. Several sensitive configuration endpoints lack admin permission checks, and multiple data-access endpoints don't scope queries to the authenticated user.
Findings
1. HIGH - SSO/OIDC/OAuth Configuration Modification (No Admin Check)
Endpoints:
POST /api/v1/config/authentication/oidc/updatePOST /api/v1/config/authentication/oauth/updateDELETE /api/v1/config/authentication
File: apps/api/src/controllers/config.ts (lines 54-189)
These endpoints have no requirePermission() or admin check. Any authenticated user (including external users) can enable SSO pointing to an attacker-controlled OIDC/OAuth provider, or delete all SSO configuration.
Secure sibling: PATCH /api/v1/config/toggle-roles (line 391) has both requirePermission(["settings::manage"]) AND explicit session?.isAdmin check.
2. HIGH - SMTP Email Configuration (No Admin Check)
Endpoints: PUT /api/v1/config/email, DELETE /api/v1/config/email
File: apps/api/src/controllers/config.ts (lines 243-388)
No admin/permission checks. Any user can redirect outgoing email through an attacker-controlled SMTP server.
3. HIGH - Cross-User Comment Deletion IDOR
Endpoint: POST /api/v1/ticket/comment/delete
File: apps/api/src/controllers/ticket.ts (lines 695-713)
await prisma.comment.delete({ where: { id: id } });No user ownership check. Compare with notebook delete (notebook.ts:83) which correctly scopes: where: { id, userId: user!.id }.
4. HIGH - Force-Logout Any User IDOR
Endpoint: GET /api/v1/auth/user/:id/logout
File: apps/api/src/controllers/auth.ts (lines 932-943)
await prisma.session.deleteMany({ where: { userId: id } });Deletes all sessions for any user ID in URL. Compare with session revocation (DELETE /api/v1/auth/sessions/:sessionId, line 1029) which correctly scopes to userId: currentUser.id.
5. MEDIUM - External User Ticket Read Bypass
Endpoint: GET /api/v1/ticket/:id
File: apps/api/src/controllers/ticket.ts (lines 249-269)
Returns full ticket details without user scoping. External users can access any ticket. Compare with external user listing (line 931) which correctly uses where: { email: user!.email }.
6. MEDIUM - Email Queue Config (No Admin Check)
Endpoints: POST /api/v1/email-queue/create, DELETE /api/v1/email-queue/delete
File: apps/api/src/controllers/queue.ts
7. LOW - Time Tracking User Attribution IDOR
Endpoint: POST /api/v1/time/new
File: apps/api/src/controllers/time.ts (lines 6-27)
userId from request body instead of session. Compare with notebook create (notebook.ts:21) which uses userId: user!.id.
Recommended Fix
- Add
requirePermission(["settings::manage"])+ admin check to config endpoints (SSO, SMTP, email queue) - Scope comment delete with
userId: user!.id - Verify
:idmatches authenticated user on logout - Scope ticket reads for external users
- Use session user ID for time tracking