
Classes and class members (classes, interfaces, fields and methods) are subject to access control in Java. The access is indicated by an access modifier: public
, protected
, private
, or the absence of an access modifier (the default access; sometimes also called package-private access).
A simplified view of the access control rules is presented in the following table. An 'x' denotes that the particular access is permitted from within that domain. For example, an x
under the heading class
means that the member is accessible to code present within the same class it is declared in. Similarly, the heading package
denotes that the member is accessible from any class (or subclass) defined in the same package, provided that at runtime, the class (or subclass) is loaded by the same class loader as that of the class containing the member. The same class loader condition only applies to package-private member access.
Access Specifier |
class |
package |
sub-class |
world |
---|---|---|---|---|
private |
x |
|
|
|
none |
x |
x |
x* |
|
protected |
x |
x |
x** |
|
public |
x |
x |
x |
x |
* Sub-classes within the same package can also access members that have no access specifiers (default or package-private visibility). An additional requirement for this is that, at runtime, the subclasses must be loaded by the same class loader as that of the class containing the package-private members. Sub-classes in a different package cannot access such package-private members.
** For referencing protected
members, the accessing class can be a sub-class in either the same or a different package.
Classes and class members should be given minimum possible access so that malicious code has the least chance of compromising their security. As far as possible, sensitive classes should avoid exposing internal functionality through interfaces because interfaces allow only public
methods, and such methods carry forward to the public Application Programming Interface (API) of the class. An exception is implementing an unmodifiable interface that exposes a public immutable view of a mutable object (SEC14-J. Provide sensitive mutable classes with unmodifiable wrappers). Additionally, note that even if a non-final class's visibility is default, it can be susceptible to misuse if it contains public methods.
Noncompliant Code Example (Public Class)
In this noncompliant code example, the class Point
is declared public. Consequently, untrusted code may instantiate Point
and invoke the public getPoint()
to obtain the coordinates.
public final class Point { private final int x; private final int y; public Point(int x, int y) { this.x = x; this.y = y; } public void getPoint() { System.out.println("(" + x + "," + y + ")"); } }
This example complies with OBJ00-J. Declare data members as private and provide accessible wrapper methods.
Compliant Solution (Final Classes With Public Methods)
This compliant solution declares the Point
class as package-private.
final class Point { private final int x; private final int y; Point(int x, int y) { this.x = x; this.y = y; } public void getPoint() { System.out.println("(" + x + "," + y + ")"); } }
A top level class such as this one, cannot be declared private. Package-private accessibility is admissible provided package insertion attacks are not possible. A package insertion attack occurs when at runtime, any protected
or package-private members of a class can be called directly by a class that is maliciously inserted into the same package. However, this attack is difficult to carry out in practice because in addition to the requirement of infiltrating into the package, the target and the untrusted class must be loaded by the same class loader. Untrusted code is typically deprived of such levels of access.
Because the class is final, the getPoint()
method can be declared public (a public subclass that violates this guideline cannot override the method and expose it to untrusted code, so its accessibility is irrelevant). For non-final classes, reducing the accessibility of methods to private or package-private eliminates this threat.
A nested class may be declared private even though the compiler changes its accessibility to package-private.
Compliant Solution (Non-final Classes With Non-public Methods)
This compliant solution declares the Point
class and its getPoint()
method as package-private. This allows the Point
class to be non-final and getPoint()
to be invoked by classes present within the same package and loaded by a common class loader.
class Point { private final int x; private final int y; Point(int x, int y) { this.x = x; this.y = y; } void getPoint() { System.out.println("(" + x + "," + y + ")"); } }
Noncompliant Code Example (Public Class With Public Static Method)
This noncompliant code example shows a public Point
class that attempts to implement instance control using a private constructor. However, untrusted code may invoke the public static getPoint()
method without instantiating the class because the class's accessibility is public.
public final class Point { private static final int x = 1; private static final int y = 2; private Point(int x, int y) {} public static void getPoint() { System.out.println("(" + x + "," + y + ")"); } }
Compliant Solution (Package-private Class)
This compliant solution reduces the accessibility of the class to package-private.
final class Point { private static final int x = 1; private static final int y = 2; private Point(int x, int y) {} public static void getPoint() { System.out.println("(" + x + "," + y + ")"); } }
Exceptions
EX1: If a class, interface, method or field is part of a published Application Programming Interface (API) such as a web service end point, it may be declared public. If not, they should be declared either package-private, protected
or private
for compliance with this guideline.
Risk Assessment
Granting unnecessary access breaks encapsulation and weakens the security of Java applications.
Rule |
Severity |
Likelihood |
Remediation Cost |
Priority |
Level |
---|---|---|---|---|---|
SEC01- J |
medium |
likely |
medium |
P12 |
L1 |
Automated Detection
TODO
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
References
[[JLS 05]] Section 6.6, Access Control
[[SCG 07]] Guideline 1-1 Limit the accessibility of classes, interfaces, methods, and fields
[[Campione 96]] Access Control
[[McGraw 00]] Chapter 3, Java Language Security Constructs
[[Bloch 08]] Item 13: Minimize the accessibility of classes and members
SEC00-J. Follow the principle of least privilege 02. Platform Security (SEC) SEC02-J. Guard doPrivileged blocks against untrusted invocations