From acc
Analyzes PHP code for authorization issues including missing access control, IDOR, privilege escalation, and role-based gaps. Use for security reviews in PHP apps.
How this skill is triggered — by the user, by Claude, or both
Slash command
/acc:check-authorizationThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Analyze PHP code for authorization and access control vulnerabilities.
Analyze PHP code for authorization and access control vulnerabilities.
// 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());
}
// 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();
}
// 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"
// 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
}
// 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;
}
// 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
// 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
// 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()
);
# 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"
| 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 |
public function getOrder(int $id): Response
{
$order = $this->orderRepository->findByIdAndUser($id, $this->getUser());
if (!$order) {
throw new NotFoundHttpException();
}
return new JsonResponse($order);
}
// Symfony Voter
if (!$this->isGranted('EDIT', $order)) {
throw new AccessDeniedException();
}
// Laravel Policy
$this->authorize('update', $order);
// 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'));
// Harder to enumerate
/api/orders/550e8400-e29b-41d4-a716-446655440000
### 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
npx claudepluginhub dykyi-roman/awesome-claude-code --plugin accAnalyzes PHP code for access control issues like inline role checks, hardcoded permissions, mixed ACL/RBAC models, missing Voter/Policy patterns, and controller authorization logic.
Detects missing ownership checks, broken role enforcement, and IDOR vulnerabilities in authorization code. Use when implementing access control middleware or resource ownership checks.
Analyzes auth mechanisms (passwords/sessions/JWT/OAuth/MFA) and authz patterns (RBAC/ABAC/ACL) for vulnerabilities like bypasses, hijacking, broken access control; reports with OWASP/NIST remediation.