Skip to content

bug(Privilege): Permission IDs with dots silently fall back to default 'PR' #404

Description

@usernane

Bug Description

Privilege::setID() only allows [A-Za-z0-9_] characters. When a permission ID contains a dot (e.g., orders.create), setID() returns false and the ID silently falls back to the default 'PR'. This causes all permissions with dots to share the same ID, so only the first one is actually registered. No error or warning is thrown.

Steps to Reproduce

use WebFiori\Framework\Access;

Access::role('customer', ['orders.create', 'orders.view', 'orders.cancel']);

$manager = Access::getManager();
$role = $manager->getRole('customer');

// Expected: 3 permissions
// Actual: 1 permission with ID 'PR'
echo count($role->privileges()); // 1
echo $role->privileges()[0]->getID(); // 'PR'

// All permission checks return true because wildcard match
var_dump($role->hasPermission('anything', $manager)); // true

Expected Behavior

Either:

  1. Dots (and dashes) should be allowed in permission IDs — they are natural separators used by every major framework
  2. Or setID() / addPermission() should throw an exception when the ID is invalid, instead of silently falling back

Actual Behavior

  • setID() returns false silently
  • Permission falls back to default ID 'PR'
  • Only one permission per role is stored (duplicates rejected by ID)
  • hasPermission() returns true for any input due to wildcard behavior
  • No error, warning, or indication that anything went wrong

WebFiori Version

v3.0.0

PHP Version

8.4.18

Operating System

Linux

Additional Context

The root cause is in Privilege::setID() (line ~92):

for ($x = 0; $x < $len; $x++) {
    $ch = $xid[$x];
    if (!($ch == '_' || ($ch >= 'a' && $ch <= 'z') || ($ch >= 'A' && $ch <= 'Z') || ($ch >= '0' && $ch <= '9'))) {
        return false;
    }
}

Suggested fix: expand to allow . and -, or throw \InvalidArgumentException on failure instead of returning false.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions