PHP Classes

File: docs/SECURITY_RBAC_TESTS.md

Recommend this page to a friend!
  Packages of Adrian M   PHP CRUD API Generator   docs/SECURITY_RBAC_TESTS.md   Download  
File: docs/SECURITY_RBAC_TESTS.md
Role: Auxiliary data
Content type: text/markdown
Description: Auxiliary data
Class: PHP CRUD API Generator
Create an API to access MySQL database record
Author: By
Last change: up
Date: 3 months ago
Size: 5,665 bytes
 

Contents

Class file image Download

Security Test: Protected System Tables

? Testing RBAC Protection for api_users Table

This document shows how the system protects sensitive tables like api_users from unauthorized access.

Test Scenario

Setup: - User "john" has role "readonly" - Role "readonly" has wildcard permissions: '*' => ['list', 'read'] - But explicitly denies: 'api_users' => []

Test 1: Admin Can Access (Expected: ? Success)

# Admin has full access to all tables including api_users
curl -u admin:secret \
  "http://localhost/PHP-CRUD-API-Generator/public/index.php?action=list&table=api_users"

# Expected Response: 200 OK
{
  "data": [
    {"id": 1, "username": "admin", "role": "admin", ...},
    {"id": 2, "username": "john", "role": "readonly", ...}
  ],
  "meta": {"page": 1, "total": 2, ...}
}

? PASS - Admin should see all users

Test 2: Readonly User Tries to Access api_users (Expected: ? Forbidden)

# Readonly user tries to list api_users table
curl -u john:password123 \
  "http://localhost/PHP-CRUD-API-Generator/public/index.php?action=list&table=api_users"

# Expected Response: 403 Forbidden
{
  "error": "Forbidden: readonly cannot list on api_users"
}

? PASS - Readonly user is blocked

Test 3: Readonly User Can Access Regular Tables (Expected: ? Success)

# Same user tries to list a regular table (e.g., posts, products)
curl -u john:password123 \
  "http://localhost/PHP-CRUD-API-Generator/public/index.php?action=list&table=posts"

# Expected Response: 200 OK
{
  "data": [...],
  "meta": {...}
}

? PASS - Regular tables work fine

Test 4: Using API Key (Expected: ? Forbidden)

# User with API key tries to access api_users
curl -H "X-API-Key: johns-readonly-api-key" \
  "http://localhost/PHP-CRUD-API-Generator/public/index.php?action=list&table=api_users"

# Expected Response: 403 Forbidden
{
  "error": "Forbidden: readonly cannot list on api_users"
}

? PASS - API key auth also respects RBAC

How It Works

1. RBAC Configuration (config/api.php)

'roles' => [
    'admin' => [
        '*' => ['list', 'read', 'create', 'update', 'delete']
    ],
    'readonly' => [
        '*' => ['list', 'read'],           // Wildcard allows all tables
        'api_users' => [],                 // But DENY api_users explicitly
        'api_key_usage' => [],             // And other system tables
    ],
],

2. Enhanced RBAC Logic (src/Rbac.php)

public function isAllowed(string $role, string $table, string $action): bool
{
    // ...
    
    // Check for explicit DENY (takes precedence over wildcards)
    if (isset($perms[$table])) {
        if (empty($perms[$table])) {
            return false;  // ? Empty array = DENY
        }
        // ...
    }
    
    // Wildcard only applies if table not explicitly defined
    // ...
}

3. Router Enforcement

Every API action calls enforceRbac():

case 'list':
    $this->enforceRbac('list', $query['table']);  // ? Checks RBAC
    $result = $this->api->list($query['table'], $opts);

Protected Tables

By default, these system tables should be protected:

| Table | Purpose | Who Can Access | |-------|---------|----------------| | api_users | User credentials & API keys | Admin only | | api_key_usage | Usage tracking | Admin only | | Any table starting with _system | Internal system tables | Admin only |

Adding More Protected Tables

To protect additional tables, add them to readonly role config:

'readonly' => [
    '*' => ['list', 'read'],
    'api_users' => [],           // Deny
    'api_key_usage' => [],       // Deny
    'audit_logs' => [],          // Deny
    'payment_methods' => [],     // Deny
    'internal_notes' => [],      // Deny
],

Security Best Practices

  1. ? Default Deny - Explicitly list protected tables
  2. ? Least Privilege - Give users minimum permissions needed
  3. ? Test Thoroughly - Run these tests after any RBAC changes
  4. ? Monitor Access - Log all attempts to access sensitive tables
  5. ? Regular Audits - Review role permissions quarterly

Quick Test Command

Run all tests at once:

# Save as test_rbac.sh or test_rbac.ps1

echo "Test 1: Admin access to api_users..."
curl -u admin:secret \
  "http://localhost/PHP-CRUD-API-Generator/public/index.php?action=list&table=api_users"

echo -e "\n\nTest 2: Readonly blocked from api_users..."
curl -u john:password123 \
  "http://localhost/PHP-CRUD-API-Generator/public/index.php?action=list&table=api_users"

echo -e "\n\nTest 3: Readonly can access regular tables..."
curl -u john:password123 \
  "http://localhost/PHP-CRUD-API-Generator/public/index.php?action=list&table=posts"

? Verification Checklist

  • [ ] Readonly users CANNOT list `api_users` table
  • [ ] Readonly users CANNOT read specific `api_users` records
  • [ ] Readonly users CANNOT create/update/delete `api_users`
  • [ ] Admin users CAN access `api_users` normally
  • [ ] Readonly users CAN access non-protected tables
  • [ ] RBAC works with both Basic Auth and API Keys
  • [ ] Monitoring logs access attempts to protected tables

Emergency: Disable Protection Temporarily

If you need to debug or temporarily allow access:

// config/api.php
'readonly' => [
    '*' => ['list', 'read'],
    // 'api_users' => [],  // ? Comment out to allow access
],

?? WARNING: Remember to re-enable protection after debugging!

Security Issue Resolved: ? System tables are now protected from unauthorized access via RBAC.