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