Authorizations granted or not to users to access resources of an application should be based on strong decisions. For instance, checking whether
the user is authenticated or not, has the right roles/privileges. It may also depend on the user’s location, or the date, time when the user requests
access.
Noncompliant Code Example
In a Symfony web application:
- the
vote
method of a VoterInterface type is not compliant when
it returns only an affirmative decision (ACCESS_GRANTED
):
class NoncompliantVoterInterface implements VoterInterface
{
public function vote(TokenInterface $token, $subject, array $attributes)
{
return self::ACCESS_GRANTED; // Noncompliant
}
}
- the
voteOnAttribute
method of a Voter type is not compliant
when it returns only an affirmative decision (true
):
class NoncompliantVoter extends Voter
{
protected function supports(string $attribute, $subject)
{
return true;
}
protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token)
{
return true; // Noncompliant
}
}
In a Laravel web application:
- the
define
, before
, and after
methods of a Gate
are not compliant when they return only an affirmative decision (true
or Response::allow()
):
class NoncompliantGuard
{
public function boot()
{
Gate::define('xxx', function ($user) {
return true; // Noncompliant
});
Gate::define('xxx', function ($user) {
return Response::allow(); // Noncompliant
});
}
}
Compliant Solution
In a Symfony web application:
- the
vote
method of a VoterInterface type should return a
negative decision (ACCESS_DENIED
) or abstain from making a decision (ACCESS_ABSTAIN
):
class CompliantVoterInterface implements VoterInterface
{
public function vote(TokenInterface $token, $subject, array $attributes)
{
if (foo()) {
return self::ACCESS_GRANTED; // Compliant
} else if (bar()) {
return self::ACCESS_ABSTAIN;
}
return self::ACCESS_DENIED;
}
}
- the
voteOnAttribute
method of a Voter type should return a
negative decision (false
):
class CompliantVoter extends Voter
{
protected function supports(string $attribute, $subject)
{
return true;
}
protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token)
{
if (foo()) {
return true; // Compliant
}
return false;
}
}
In a Laravel web application:
- the
define
, before
, and after
methods of a Gate
should return a negative decision (false
or Response::deny()
) or abstain from making a decision (null
):
class NoncompliantGuard
{
public function boot()
{
Gate::define('xxx', function ($user) {
if (foo()) {
return true; // Compliant
}
return false;
});
Gate::define('xxx', function ($user) {
if (foo()) {
return Response::allow(); // Compliant
}
return Response::deny();
});
}
}
See