ZF-Commons / zfc-rbac

Role-based access control module to provide additional features on top of Zend\Permissions\Rbac
BSD 3-Clause "New" or "Revised" License
181 stars 111 forks source link

Firewall Route Access bypass #49

Closed neoglez closed 11 years ago

neoglez commented 11 years ago

Given the following settings: Role Provider: ZfcRbac\Provider\AdjacencyList\Role\DoctrineDbal Permission Provider: ZfcRbac\Provider\Generic\Permission\DoctrineDbal

Anonymous role (id): 'guest' Administrator role (id): 'admin', admin inherits from 'guest' (e.g. access to login page, etc.)

Define a ROUTE Firewall: 'ZfcRbac\Firewall\Route' => array( array('route' => 'admin', 'roles' => 'admin') ),

Then 'guest' users can access the route 'admin', bypassing the firewall!

tranba commented 11 years ago

Do you have 'guest' and 'admin' roles in the permission table?

neoglez commented 11 years ago

@tramba, here is the mapping: rbac_access_bypass

neoglez commented 11 years ago

I think the problem is in the conception; under the following definitions (taken from http://framework.zend.com/manual/2.1/en/modules/zend.permissions.rbac.intro.html):

an identity has one or more roles.
a role requests access to a permission.
a permission is given to a role.

Thus, RBAC has the following model:

many to many relationship between identities and roles.
many to many relationship between roles and permissions.
roles can have a parent role.

The route firewall can not only check if the RBAC service has the role since RBAC will ALWAYS have the role when you load roles from a DB

tranba commented 11 years ago

I'm sorry, I'm mistaken.I mean you've got the 'guest' role in the rbac_role table? If anonymous role is 'guest' and in the rbac_role table not have the 'guest' role, firewall CONTROLLER will be bypass but firewall ROUTE will throw a exception. In your case, do you have set 'firewallRoute' => true in the zfcrbac.global.php file ? Sorry for my english.

neoglez commented 11 years ago

@tramba Yes, firewallRoute' => true in the zfcrbac.global.php file and the data in DB is totally consistent ('guest' is in the corresponding tables). Like i said, the problem is in the conception, children roles INHERIT permissions from parents and not the other way around, that is to say if a RBAC has a role (let's say 'admin') and 'admin' has a parent role 'guest', then RBAC must also have the role 'guest'. At the momment the logic in ZfcRbac\Service\Rbac is upside down: // Last resort - check children from rbac. $it = new RecursiveIteratorIterator($rbac->getRole($userRole), RecursiveIteratorIterator::CHILD_FIRST); foreach($it as $leaf) { if ($leaf->getName() == $role) { return true; } }

I think it's the parents that must be checked and NOT the CHILDREN, Children inherit from parents (NOT parent from children)

danizord commented 11 years ago

@neoglez, According to the hierarchical model of RBAC, parents have the permissions of their children. How can a child do something that his father can not? See https://github.com/zendframework/zf2/issues/3265

neoglez commented 11 years ago

@Danizord Thanks for the reference! In fact children CAN and USUALLY DO things that their parents can not, but as you pointed out in http://csrc.nist.gov/rbac/sandhu-ferraiolo-kuhn-00.pdf we can read: "(...) whereby senior roles acquire the permissions of their juniors. (...)" So, i think that ends the discussion :)

danizord commented 11 years ago

@neoglez Exactly, It is just the inverse of the ACL inheritance, the parents inherit the permissions of their children instead of the children inherit the permissions of their parent.

neoglez commented 11 years ago

@Danizord Thanks again!

Freeaqingme commented 11 years ago

I've merged the documentation PR. This change will be reflected in the online documentation when they are updated (probably later this week).

danizord commented 11 years ago

Thanks @Freeaqingme

spiffyjr commented 11 years ago

Thanks @Freeaqingme