$npx -y skills add utkusen/sast-skills --skill sast-missingauthDetect missing authentication and broken function-level authorization vulnerabilities in a codebase using a three-phase approach: recon (map endpoints and the role/permission system), batched verify (check auth/authz in parallel subagents, 3 endpoints each), and merge (consolidat
| 1 | # Missing Authentication & Broken Function-Level Authorization Detection |
| 2 | |
| 3 | You are performing a focused security assessment to find missing authentication and broken function-level authorization vulnerabilities in a codebase. This skill uses a three-phase approach with subagents: **recon** (map endpoints and the permission system), **batched verify** (check authentication and authorization in parallel batches of 3 endpoints each), and **merge** (consolidate batch results into the final report). |
| 4 | |
| 5 | **Prerequisites**: `sast/architecture.md` must exist. Run the analysis skill first if it doesn't. |
| 6 | |
| 7 | --- |
| 8 | |
| 9 | ## What This Skill Covers |
| 10 | |
| 11 | ### Missing Authentication |
| 12 | An endpoint performs a sensitive action but requires **no login at all** — any anonymous HTTP request can trigger it. |
| 13 | |
| 14 | ### Broken Function-Level Authorization |
| 15 | An endpoint requires authentication (user must be logged in) but **does not check whether the authenticated user has the required role or permission** to invoke that function. The classic example: a regular user calling an admin-only API. |
| 16 | |
| 17 | ### What This Skill Is NOT |
| 18 | |
| 19 | Do not conflate with: |
| 20 | - **IDOR / Horizontal privilege escalation**: Authenticated user A accessing user B's resource by changing an ID. This skill covers **vertical** privilege escalation and unauthenticated access. |
| 21 | - **JWT weaknesses**: Flawed token signing/verification (covered by sast-jwt). |
| 22 | - **Business logic flaws**: Price manipulation, workflow bypass — these are separate. |
| 23 | |
| 24 | --- |
| 25 | |
| 26 | ## Vulnerability Classes |
| 27 | |
| 28 | ### Class 1: Unauthenticated Sensitive Endpoint |
| 29 | The endpoint modifies data, returns private information, or performs an administrative action — with no authentication required. |
| 30 | |
| 31 | ``` |
| 32 | GET /api/admin/users → returns full user list, no token needed |
| 33 | DELETE /api/admin/users/5 → deletes a user, no token needed |
| 34 | POST /api/settings/smtp → updates server config, no token needed |
| 35 | ``` |
| 36 | |
| 37 | ### Class 2: Authenticated but Missing Role Check |
| 38 | The endpoint requires a valid session/token but performs no role or permission check. Any authenticated user — regardless of role — can invoke admin or privileged functions. |
| 39 | |
| 40 | ``` |
| 41 | Regular user sends: |
| 42 | DELETE /api/admin/users/5 |
| 43 | Authorization: Bearer <regular_user_token> |
| 44 | → Server deletes the user without checking if the caller is an admin |
| 45 | ``` |
| 46 | |
| 47 | ### Class 3: Incomplete or Bypassable Authorization |
| 48 | Authorization logic is present but can be bypassed: |
| 49 | - Role check exists in the GET handler but not in the corresponding DELETE/POST handler |
| 50 | - Role check is conditional on a request header or parameter the attacker controls |
| 51 | - Middleware is registered but the route is mounted before the middleware applies |
| 52 | |
| 53 | --- |
| 54 | |
| 55 | ## Authorization Patterns That PREVENT Vulnerabilities |
| 56 | |
| 57 | When you see these patterns, the endpoint is likely **not vulnerable**: |
| 58 | |
| 59 | **1. Authentication + role-check middleware on a route group** |
| 60 | ```javascript |
| 61 | // Express: all /admin routes protected |
| 62 | router.use('/admin', auth, requireRole('admin')); |
| 63 | router.delete('/admin/users/:id', deleteUser); // protected by above |
| 64 | |
| 65 | // Flask-Login + custom decorator |
| 66 | @app.route('/admin/users') |
| 67 | @login_required |
| 68 | @admin_required |
| 69 | def list_users(): ... |
| 70 | ``` |
| 71 | |
| 72 | **2. Declarative role annotations (Java / Spring)** |
| 73 | ```java |
| 74 | @PreAuthorize("hasRole('ADMIN')") |
| 75 | @DeleteMapping("/api/admin/users/{id}") |
| 76 | public ResponseEntity<?> deleteUser(@PathVariable Long id) { ... } |
| 77 | ``` |
| 78 | |
| 79 | **3. In-handler role check before sensitive action** |
| 80 | ```python |
| 81 | # Django |
| 82 | @login_required |
| 83 | def delete_user(request, user_id): |
| 84 | if not request.user.is_staff: |
| 85 | return HttpResponseForbidden() |
| 86 | User.objects.filter(id=user_id).delete() |
| 87 | return HttpResponse(status=204) |
| 88 | ``` |
| 89 | |
| 90 | **4. Middleware gate applied to entire prefix** |
| 91 | ```go |
| 92 | // Chi router — admin group protected |
| 93 | r.Group(func(r chi.Router) { |
| 94 | r.Use(AdminOnly) |
| 95 | r.Delete("/admin/users/{id}", deleteUser) |
| 96 | }) |
| 97 | ``` |
| 98 | |
| 99 | **5. Policy/Gate objects** |
| 100 | ```php |
| 101 | // Laravel Gate |
| 102 | Gate::define('admin-action', fn($user) => $user->role === 'admin'); |
| 103 | // In controller |
| 104 | $this->authorize('admin-action'); |
| 105 | ``` |
| 106 | |
| 107 | --- |
| 108 | |
| 109 | ## Vulnerable vs. Secure Examples |
| 110 | |
| 111 | ### Python — Django |
| 112 | |
| 113 | ```python |
| 114 | # VULNERABLE: No authentication at all |
| 115 | def list_all_users(request): |
| 116 | users = User.objects.values('id', 'email', 'is_staff') |
| 117 | return JsonResponse(list(users), safe=False) |
| 118 | |
| 119 | # VULNERABLE: Authenticated but no role check |
| 120 | @login_required |
| 121 | def delete_user(requ |