Check authorization
Skill dykyi-roman/awesome-claude-code/skills/check-authorization
Analyzes PHP code for authorization issues. Detects missing access control, IDOR vulnerabilities, privilege escalation, role-based access gaps.From its SKILL.md
npx -y skills add dykyi-roman/awesome-claude-code --skill check-authorizationAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
SKILL.md
5.6 KB, as published. Nobody here has run it
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