Awesome-claude-code check-authorization
Analyzes PHP code for authorization issues. Detects missing access control, IDOR vulnerabilities, privilege escalation, role-based access gaps.
install
source · Clone the upstream repo
git clone https://github.com/dykyi-roman/awesome-claude-code
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/dykyi-roman/awesome-claude-code "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/check-authorization" ~/.claude/skills/dykyi-roman-awesome-claude-code-check-authorization && rm -rf "$T"
manifest:
skills/check-authorization/SKILL.mdsource content
Authorization Security Check
Analyze PHP code for authorization and access control vulnerabilities.
Detection Patterns
1. Missing Access Control Checks
// CRITICAL: No authorization public function deleteUser(int $id): Response { $user = $this->userRepository->find($id); $this->userRepository->delete($user); // Anyone can delete any user! } // CRITICAL: Only checking authentication, not authorization public function updateOrder(int $orderId): Response { if (!$this->getUser()) { throw new UnauthorizedException(); } // Auth check present, but no ownership check $order = $this->orderRepository->find($orderId); $order->update($this->request->all()); }
2. IDOR (Insecure Direct Object Reference)
// CRITICAL: Direct ID from user input $order = $this->orderRepository->find($_GET['id']); return new JsonResponse($order); // CRITICAL: Sequential ID enumeration /api/users/1 /api/users/2 /api/users/3 // Attacker iterates through all users // CORRECT: Ownership check $order = $this->orderRepository->findByIdAndUser($id, $currentUser); if (!$order) { throw new NotFoundException(); }
3. Privilege Escalation
// CRITICAL: Role from user input $user->setRole($_POST['role']); // User sets own role // CRITICAL: Mass assignment vulnerability $user->fill($request->all()); // Could include 'is_admin' // VULNERABLE: Hidden field role <input type="hidden" name="role" value="user"> // Attacker changes to "admin"
4. Horizontal Privilege Escalation
// CRITICAL: Can access other users' data public function getProfile(int $userId): Response { return new JsonResponse( $this->userRepository->find($userId) ); // User A can view User B's profile } // CRITICAL: Can modify other users' resources public function updateProfile(int $userId, array $data): void { $user = $this->userRepository->find($userId); $user->update($data); // No check if $userId === currentUser->id }
5. Vertical Privilege Escalation
// CRITICAL: Admin function accessible to users #[Route('/admin/users')] public function listUsers(): Response { // No role check return new JsonResponse($this->userRepository->findAll()); } // VULNERABLE: Role check can be bypassed if ($request->get('bypass_check') === 'true') { $this->isAdmin = true; }
6. Path/Action Based Authorization Gaps
// VULNERABLE: Only checking some endpoints // /api/users - protected // /api/users/export - NOT protected // VULNERABLE: Different behavior for same resource // GET /orders/1 - ownership checked // DELETE /orders/1 - no ownership check
7. JWT/Token Authorization Issues
// CRITICAL: Trusting JWT claims without verification $payload = json_decode(base64_decode(explode('.', $jwt)[1])); if ($payload->role === 'admin') { } // CRITICAL: Algorithm confusion // Server accepts 'none' algorithm // VULNERABLE: No token expiry check $token = $this->jwtService->decode($jwt); // No check for exp claim
8. Resource-Based Access Control Gaps
// VULNERABLE: Checking role but not resource ownership if ($this->isAdmin()) { $document = $this->documentRepository->find($id); return $document; // Admin sees ALL documents across organizations } // CORRECT: Scope to organization $document = $this->documentRepository->findByIdAndOrganization( $id, $currentUser->getOrganization() );
Grep Patterns
# Repository find without ownership Grep: "Repository->find\(\\\$_|Repository->find\(\\\$request" --glob "**/*.php" # Direct object access Grep: "find\(\\\$id\)\s*;" --glob "**/*.php" # Role from user input Grep: "setRole\(\\\$_|setRole\(\\\$request" --glob "**/*.php" # Mass assignment Grep: "->fill\(\\\$request|->update\(\\\$request" --glob "**/*.php"
Severity Classification
| Pattern | Severity |
|---|---|
| Missing access control | 🔴 Critical |
| IDOR vulnerability | 🔴 Critical |
| Privilege escalation from input | 🔴 Critical |
| Horizontal access violation | 🔴 Critical |
| Role bypass mechanism | 🔴 Critical |
| Missing resource scoping | 🟠 Major |
| Inconsistent auth on endpoints | 🟠 Major |
Best Practices
Always Check Ownership
public function getOrder(int $id): Response { $order = $this->orderRepository->findByIdAndUser($id, $this->getUser()); if (!$order) { throw new NotFoundHttpException(); } return new JsonResponse($order); }
Use Voters/Policies
// Symfony Voter if (!$this->isGranted('EDIT', $order)) { throw new AccessDeniedException(); } // Laravel Policy $this->authorize('update', $order);
Protected Mass Assignment
// Laravel protected $fillable = ['name', 'email']; // Whitelist protected $guarded = ['is_admin', 'role']; // Blacklist // Explicit assignment $user->setName($request->get('name')); // Never: $user->setRole($request->get('role'));
UUIDs Instead of Sequential IDs
// Harder to enumerate /api/orders/550e8400-e29b-41d4-a716-446655440000
Output Format
### Authorization Issue: [Description] **Severity:** 🔴/🟠/🟡 **Location:** `file.php:line` **CWE:** CWE-862 (Missing Authorization) **Issue:** [Description of the authorization weakness] **Attack Vector:** Attacker can access/modify resources belonging to other users. **Code:** ```php // Vulnerable code
Fix:
// With proper authorization