yiisoft / yii2

Yii 2: The Fast, Secure and Professional PHP Framework

Home Page:http://www.yiiframework.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Variable $roleParams not set before isset check in yii\filters\AccessRule::matchRole function

santilin opened this issue · comments

In the matchRole function of the AccessRule class, the variable $roleParams is not set before the isset($roleParams) condition.

The problematic code is:

if (!isset($roleParams)) {
    $roleParams = !is_array($this->roleParams) && is_callable($this->roleParams) ? call_user_func($this->roleParams, $this) : $this->roleParams;
}

This code assumes that $roleParams is already defined, but it is not set anywhere before this condition.
Steps to Reproduce

  • Set $this->roleParams to a non-array value (e.g., null, false, or a string) in your AccessRule configuration.
  • Call the matchRole function with a user object that does not have the required permissions.

Expected Behavior
The matchRole function should handle the case where $this->roleParams is not an array or callable, and it should not assume that $roleParams is already defined.

Yii2 version: 2.0.50
PHP version: 8.3

Set $this->roleParams to a non-array value (e.g., null, false, or a string) in your AccessRule configuration.

$roleParams accepts only Closure or array, if you pass null, false, or a string, then it is a configuration error.

https://www.yiiframework.com/doc/api/2.0/yii-filters-accessrule#$roleParams-detail

Yet, ¿but what is the point of testing

not isset($roleParams)

when the local variable $roleParams is not defined?

That test will always return false.

It is inside of foreach, so it is empty for first iteration, but each next iteration will use already calculated value. In this way Closure is executed only once and only when it is actually needed.

Ah, ok, I didn't understand that.
Thanks.