
Classes and class members (classes, interfaces, fields, and methods) are subject to access control -controlled in Java. The access is indicated by an access modifier : (public
, protected
, or private
, ) or by the absence of an access modifier (the default access; sometimes , also called package-private access).
A The following table presents a simplified view of the access control rules is presented in the following table. An 'x' denotes indicates that the particular access is permitted from within that domain. For example, an x under in the heading class column means that the member is accessible to code present within the same class in which it is declared in. LikewiseSimilarly, the heading package denotes column indicates 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 loaded the class containing the member. The same class loader condition applies only applies to package-private member access.
Access Specifier |
---|
Class |
---|
Package |
---|
Subclass |
---|
World | |
---|---|
| x |
None | x | x | x* |
---|
| x | x | x** |
---|
| x | x | x | x |
---|
* Sub-classes Subclasses within the same package can also access members that have no lack access specifiers (default or package-private visibility). An additional requirement for this access is that , at runtime, the subclasses must be loaded by the same class loader as that of loaded the class containing the package-private members. Sub-classes Subclasses in a different package cannot access such package-private members.
** For referencing protected
membersTo reference a protected member, the accessing class can be a sub-class in either the same or a different packagecode must be contained either in the class that defines the protected member or in a subclass of that defining class. Subclass access is permitted without regard to the package location of the subclass.
Classes and class members should must be given the minimum possible access so that malicious code has the least chance of compromising their opportunity to compromise security. As far as possible, sensitive classes should avoid implementing interfaces. This is because only public
methods are allowed to be declared within interfaces and these carry forward to the public Application Programming Interface exposing methods that contain (or invoke) sensitive code through interfaces; interfaces allow only publicly accessible methods, and such methods are part of the public application programming interface (API) of the class. An exception . (Note that this is the opposite of Joshua Bloch's recommendation to prefer interfaces for APIs [Bloch 2008, Item 16].) One exception to this is implementing an unmodifiable interface that exposes a public immutable view of a mutable object. (SEC14See OBJ04-J. Provide sensitive mutable classes with unmodifiable wrappers). Additionally, be aware copy functionality to safely allow passing instances to untrusted code.) Note that even if a nonfinal class's visibility is default, it can be susceptible to misuse if it exposes a public
methodcontains public methods. Methods that perform all necessary security checks and sanitize all inputs may be exposed through interfaces.
Protected accessibility is invalid for non-nested classes, but nested classes may be declared protected. Fields of nonfinal public classes should rarely be declared protected; untrusted code in another package can subclass the class and access the member. Furthermore, protected members are part of the API of the class and consequently require continued support. OBJ01-J. Declare data members as private and provide accessible wrapper methods recommends declaring fields as private.
If a class, interface, method, or field is part of a published API, such as a web service endpoint, it may be declared public. Other classes and members should be declared either package-private or private. For example, non-security-critical classes are encouraged to provide public static factories to implement instance control with a private constructor.
Noncompliant Code Example
...
(Public Class)
This noncompliant code example defines a class that is internal to a system and not part of any public API. Nonetheless, this class is declared public. In this noncompliant example, the class PublicClass
is declared public
. The member method getPoint
as well as the (x, y)
coordinates are also declared public
. This gives world-access to the class members.
Code Block | ||
---|---|---|
| ||
public final class PublicClassPoint { private publicfinal 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 + ")"); } } |
Note that a non-public class is also vulnerable if its members are declared public
(a violation of OBJ00Even though this example complies with OBJ01-J. Declare data members as private and provide accessible wrapper methods, untrusted code could instantiate Point
and invoke the public getPoint()
method to obtain the coordinates.
Compliant Solution
...
(Final Classes with Public Methods)
This compliant solution declares the Point
class as package-private in accordance with its status as not part of any public API:Limiting the scope of classes, interfaces, methods and fields as far as possible reduces the chance of malicious manipulation. Limit the accessibility depending on the desired implementation scope. For non-final classes, reducing the accessibility of methods also eliminates the threat of malicious overriding. This compliant solution demonstrates the most restrictive accessibility.
Code Block | ||
---|---|---|
| ||
final class PrivateClassPoint { private final int x; private final int y; Point(int x, int y) { this.x = x; this.y = y; } privatepublic void getPoint() { System.out.println("(" + x + "," + y + ")"); } } |
A top-level class, such as this one Point
, cannot be declared as private. Package-private accessibility is admissible in this case. However, nested classes may be declared as private
.
Compliant Solution
At acceptable provided package insertion attacks are avoided. (See ENV01-J. Place all security-sensitive code in a single JAR and sign and seal it.) 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 (package insertion attack). However, this attack is difficult to carry out in practice because, in addition to the aforementioned requirement of infiltrating into the package, both the target as well as and the untrusted classes 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 rule cannot override the method and expose it to untrusted code, so its accessibility is irrelevant. For nonfinal classes, reducing the accessibility of methods to private or package-private eliminates this threat.
Compliant Solution (Nonfinal Classes with Nonpublic Methods)
This compliant solution declares the Point
class and its getPoint()
method with as package-private accessibility and relaxes the requirements of the previous compliant solution. This allows classes , which allows the Point
class to be nonfinal and allows getPoint()
to be invoked by classes present within the same package , and loaded by a common class loader, to access the method.:
Code Block | ||
---|---|---|
| ||
final class PrivateClassPoint { 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 + ")"); } } |
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
Wiki Markup |
---|
\[[JLS 05|AA. Java References#JLS 05]\] [Section 6.6, Access Control|http://java.sun.com/docs/books/jls/third_edition/html/names.html#6.6]
\[[SCG 07|AA. Java References#SCG 07]\] Guideline 1-1 Limit the accessibility of classes, interfaces, methods, and fields
\[[Campione 96|AA. Java References#Campione 96]\] [Access Control|http://www.telecom.ntua.gr/HTML.Tutorials/java/javaOO/accesscontrol.html]
\[[McGraw 00|AA. Java References#McGraw 00]\] Chapter 3, Java Language Security Constructs
\[[Bloch 08|AA. Java References#Bloch 08]\] Item 13: Minimize the accessibility of classes and members |
Noncompliant Code Example (Public Class with Public Static Method)
This noncompliant code example again defines a class that is internal to a system and not part of any public API. Nonetheless, the class Point
is declared public.
Code Block | ||
---|---|---|
| ||
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 + ")");
}
}
|
Even though this example complies with OBJ01-J. Declare data members as private and provide accessible wrapper methods, untrusted code could access Point
and invoke the public static getPoint()
to obtain the default coordinates. The attempt to implement instance control using a private constructor is futile because the public static method exposes internal class contents.
Compliant Solution (Package-Private Class)
This compliant solution reduces the accessibility of the class to package-private:
Code Block | ||
---|---|---|
| ||
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 + ")");
}
}
|
Access to the getPoint()
method is restricted to classes located within the same package. Untrusted code is prevented from invoking getPoint()
and obtaining the coordinates.
Applicability
Granting excessive access breaks encapsulation and weakens the security of Java applications.
A system with an API designed for use (and possibly extended) by third-party code must expose the API through a public interface. The demands of such an API override this guideline.
For any given piece of code, the minimum accessibility for each class and member can be computed so as to avoid introducing compilation errors. A limitation is that the result of this computation may lack any resemblance to what the programmer intended when the code was written. For example, unused members can obviously be declared to be private. However, such members could be unused only because the particular body of code examined coincidentally lacks references to the members. Nevertheless, this computation can provide a useful starting point for a programmer who wishes to minimize the accessibility of classes and their members.
Automated Detection
Tool | Version | Checker | Description | ||||||
---|---|---|---|---|---|---|---|---|---|
Parasoft Jtest |
| CERT.OBJ51.DPAF | Declare package-private fields as inaccessible as possible Declare package-private methods as inaccessible as possible Declare "package-private" types as inaccessible as possible Declare "public/protected" types as inaccessible as possible Declare "public/protected" fields as inaccessible as possible Declare "public/protected" methods as inaccessible as possible |
Bibliography
Item 13, "Minimize the Accessibility of Classes and Members" | |
[JLS 2014] | |
Chapter 3, "Java Language Security Constructs" |
...
SEC00-J. Follow the principle of least privilege 02. Platform Security (SEC) SEC02-J. Guard doPrivileged blocks against untrusted invocations