When granting users access to resources of an application, such an authorization should be based on strong decisions. For instance, a user may be authorized to access a resource only if they are authenticated, or if they have the correct role and privileges.

Why is this an issue?

Access control is a critical aspect of web frameworks that ensures proper authorization and restricts access to sensitive resources or actions. To enable access control, web frameworks offer components that are responsible for evaluating user permissions and making access control decisions. They might examine the user’s credentials, such as roles or privileges, and compare them against predefined rules or policies to determine whether the user should be granted access to a specific resource or action.

Conventionally, these checks should never grant access to every request received. If an endpoint or component is meant to be public, then it should be ignored by access control components. Conversely, if an endpoint should deny some users from accessing it, then access control has to be configured correctly for this endpoint.

Granting unrestricted access to all users can lead to security vulnerabilities and potential misuse of critical functionalities. It is important to carefully assess access decisions based on factors such as user roles, resource sensitivity, and business requirements. Implementing a robust and granular access control mechanism is crucial for the security and integrity of the web application itself and its surrounding environment.

What is the potential impact?

Not verifying user access strictly can introduce significant security risks. Some of the most prominent risks are listed below. Depending on the use case, it is very likely that other risks are introduced on top of the ones listed.

Unauthorized access

As the access of users is not checked strictly, it becomes very easy for an attacker to gain access to restricted areas or functionalities, potentially compromising the confidentiality, integrity, and availability of sensitive resources. They may exploit this access to perform malicious actions, such as modifying or deleting data, impersonating legitimate users, or gaining administrative privileges, ultimately compromising the security of the system.

Theft of sensitive data

Theft of sensitive data can result from incorrect access control if attackers manage to gain access to databases, file systems, or other storage mechanisms where sensitive data is stored. This can lead to the theft of personally identifiable information (PII), financial data, intellectual property, or other confidential information. The stolen data can be used for various malicious purposes, such as identity theft, financial fraud, or selling the data on the black market, causing significant harm to individuals and organizations affected by the breach.

How to fix it in Spring

Code examples

Noncompliant code example

The vote method of an AccessDecisionVoter implementation is not compliant when it returns only an affirmative decision (ACCESS_GRANTED) or abstains to make a decision (ACCESS_ABSTAIN):

public class WeakNightVoter implements AccessDecisionVoter {
    @Override
    public int vote(Authentication authentication, Object object, Collection collection) {
        Calendar calendar = Calendar.getInstance();
        int currentHour = calendar.get(Calendar.HOUR_OF_DAY);

        if (currentHour >= 8 && currentHour <= 19) {
            return ACCESS_GRANTED;
        }

        return ACCESS_ABSTAIN; // Noncompliant: when users connect during the night, no decision is made
    }
}

The hasPermission method of a PermissionEvaluator implementation is not compliant when it doesn’t return false:

public class MyPermissionEvaluator implements PermissionEvaluator {
    @Override
    public boolean hasPermission(Authentication authentication, Object targetDomainObject, Object permission) {
        Object user = authentication.getPrincipal();

        if (user.getRole().equals(permission)) {
              return true;
        }

        return true; // Noncompliant
    }
}

Compliant solution

The vote method of an AccessDecisionVoter implementation should return a negative decision (ACCESS_DENIED):

public class StrongNightVoter implements AccessDecisionVoter {
    @Override
    public int vote(Authentication authentication, Object object, Collection collection) {
        Calendar calendar = Calendar.getInstance();
        int currentHour = calendar.get(Calendar.HOUR_OF_DAY);

        if (currentHour >= 8 && currentHour <= 19) {
            return ACCESS_GRANTED;
        }

        return ACCESS_DENIED; // Users are not allowed to connect during the night
    }
}

The hasPermission method of a PermissionEvaluator implementation should return false:

public class MyPermissionEvaluator implements PermissionEvaluator {
    @Override
    public boolean hasPermission(Authentication authentication, Object targetDomainObject, Object permission) {
        Object user = authentication.getPrincipal();

        if (user.getRole().equals(permission)) {
              return true;
        }

        return false;
    }
}

Resources

Standards