Security Check In Overridable Method

ID

java.security_check_in_overridable_method

Severity

high

Resource

Injection

Language

Java

Tags

CWE:358, NIST.SP.800-53, OWASP:2021:A4, PCI-DSS:6.5.6

Description

A security check is performed within an overridable method.

Rationale

In Java, the use of inheritance and method overriding is common for extending functionality. However, when critical security checks or sensitive logic are placed in methods that can be overridden, it introduces a risk. Attackers or malicious developers can create subclasses that override these methods to bypass security checks or alter the intended security behavior.

The Common Weakness Enumeration (CWE) 358 outlines risks associated with designing applications where security-critical methods can be overridden. This allows malicious subclasses to change the method logic, bypassing access controls or authentication mechanisms.

Consider a Java class where a security check is implemented in a method designed to be overridden:

public class SecurityManager {
    public boolean isUserAuthorized(User user) {
        // Perform security check
        return checkUserCredentials(user);
    }

    protected boolean checkUserCredentials(User user) {
        // Placeholder logic - Vulnerable to being overridden
        return user.hasValidSession();
    }
}

class MaliciousUser extends SecurityManager {
    @Override
    protected boolean checkUserCredentials(User user) {
        // Bypass security by always returning true
        return true;
    }
}

In this example, the checkUserCredentials method is a potential point of exploitation when subclassed, allowing unauthorized access by bypassing the security check.

Remediation

To safeguard against vulnerabilities involving security logic in overridable methods, apply the following strategies within Java applications:

  1. Use the final Modifier: Mark security-critical methods as final to prevent them from being overridden in subclasses.

    public class SecurityManager {
        public final boolean isUserAuthorized(User user) {
            return checkUserCredentials(user);
        }
    
        private boolean checkUserCredentials(User user) {
            return user.hasValidSession();
        }
    }
  2. Perform Security Checks in Immutable Classes: Design classes containing security logic to be immutable, reducing the risk of manipulating security-sensitive data.

  3. Centralize Security Logic: Implement central security mechanisms (such as utility classes or security services) outside of overridable code paths.

  4. Security Auditing and Testing: Regularly review code for security-critical paths and conduct thorough security testing to ensure all potential bypass routes are identified and mitigated.

By applying these measures, developers can prevent security checks from being bypassed via method overriding, maintaining the integrity and security of Java applications.