dykyi-roman

check-authorization

Analyzes PHP code for authorization issues. Detects missing access control, IDOR vulnerabilities, privilege escalation, role-based access gaps.

dykyi-roman 78 18 Updated 3mo ago
GitHub

Install

npx skillscat add dykyi-roman/awesome-claude-code/check-authorization

Install via the SkillsCat registry.

SKILL.md

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