
According to the The Java Language Specification \[[JLS 05|AA. Java References#JLS 05]\], the keyword {{this}} denotesSpecification, §15.8.3, " Wiki Markup
" [JLS 2015]:this
When used as a primary expression, the keyword
this
denotes a value that is a reference to the object for which the instance method was invoked (§15§15.12), or to the object being constructed....The type of
this
is the classC
or interface type T within which the keywordthis
occurs....At run time, the class of the actual object referred to may be the class
C
or any subclass ofC
T, if T is a class type, or a class that is a subtype of T.
The this
reference is said to have escaped when it is made available beyond its current scope. Common Following are common ways by which the this
reference can escape include:
Returning
non-private methodthis
from a- Passing
this
as a parameter to a method belonging to another class - Publishing
this
from the constructor of an object under construction - Publishing
this
such that pieces of code beyond its current scope can obtain its reference - Calling a non-final method from a constructor (MET32-J. Ensure that constructors do not call overridable methods)
- Overriding the finalizer of a non-final class when its construction ceases (OBJ32-J. Do not allow partially initialized objects to be accessed). This is a special case of the previous point.
This guideline primarily focuses on the ill effects of this
escaping during object construction. Potential consequences include race conditions and improper initialization.
Noncompliant Code Example
This noncompliant code example defines the ExceptionReporter
interface that is implemented by the class ExceptionReporters
. This class is useful for reporting exceptions after filtering out any sensitive information (EXC05-J. Use a class dedicated to reporting exceptions). The constructor of ExceptionReporters
, incorrectly publishes the this
reference before construction of the object has concluded. This is because it sets the exception reporter in the constructor (statement er.setExceptionReporter(this)
). It is misleading that, because it is the last statement in the constructor, it must be benign.
The class MyExceptionReporter
subclasses ExceptionReporters
with the intent of adding a logging mechanism that logs critical messages before an exception is reported. Its constructor invokes the superclass's constructor (a mandatory first step) which publishes the exception reporter, before the initialization of the subclass has concluded. Note that the subclass initialization consists of obtaining an instance of the default logger.
Consequently, the exception handler is set. If any exception occurs before the call to Logger.getLogger
in the subclass, it is not logged. Instead, a NullPointerException
is generated which may again get swallowed by the reporting mechanism.
In summary, this behavior is due to the race condition between an oncoming exception and the initialization of the subclass. If the exception comes too soon, it finds the subclass in a compromised state. This behavior is even more counter intuitive because logger
is declared final
and is not expected to contain an unintialized value.
nonprivate, overridable method that is invoked from the constructor of a class whose object is being constructed (for more information, see MET05-J. Ensure that constructors do not call overridable methods).
- Returning
this
from a nonprivate method of a mutable class, which allows the caller to manipulate the object's state indirectly. This situation commonly occurs in method-chaining implementations (see VNA04-J. Ensure that calls to chained methods are atomic for more information). - Passing
this
as an argument to an alien method invoked from the constructor of a class whose object is being constructed. - Using inner classes. An inner class implicitly holds a reference to the instance of its outer class unless the inner class is declared static.
- Publishing by assigning
this
to a public static variable from the constructor of a class whose object is being constructed. - Throwing an exception from a constructor. Doing so may cause code to be vulnerable to a finalizer attack (see OBJ11-J. Be wary of letting constructors throw exceptions for more information).
- Passing internal object state to an alien method, which enables the method to retrieve the
this
reference of the internal member object.
This rule describes the potential consequences of allowing the this
reference to escape during object construction, including race conditions and improper initialization. For example, declaring a field final ordinarily ensures that all threads see the field in a fully initialized state; however, allowing the this
reference to escape during object construction can expose the field to other threads in an uninitialized or partially initialized state. TSM03-J. Do not publish partially initialized objects, which describes the guarantees provided by various mechanisms for safe publication, relies on conformance to this rule. Consequently, programs must not allow the this
reference to escape during object construction.
In general, it is important to detect cases in which the this
reference can leak out beyond the scope of the current context. In particular, public variables and methods should be carefully scrutinized.
Noncompliant Code Example (Publish before Initialization)
This noncompliant code example publishes the this
reference before initialization has concluded by storing it in a public static volatile class field. Consequently, other threads can obtain a partially initialized Publisher
instance.
Code Block | ||
---|---|---|
| ||
final class Publisher {
public static volatile Publisher published;
int num;
Publisher(int number) {
published = this;
// Initialization
this.num = number;
// ...
}
}
|
If an object's initialization (and consequently, its construction) depends on a security check within the constructor, the security check can be bypassed when an untrusted caller obtains the partially initialized instance (see OBJ11-J. Be wary of letting constructors throw exceptions for more information).
Noncompliant Code Example (Nonvolatile Public Static Field)
This noncompliant code example publishes the this
reference in the last statement of the constructor. It remains vulnerable because the published
field has public accessibility and the programmer has failed to declare it as volatile.
Code Block | ||
---|---|---|
| ||
final class Publisher {
public static Publisher published;
int num;
Publisher(int number) {
// Initialization
this.num = number;
// ...
published = this;
}
}
|
Because the field is nonvolatile and nonfinal, the statements within the constructor can be reordered by the compiler in such a way that the this
reference is published before the initialization statements have executed.
Compliant Solution (Volatile Field and Publish after Initialization)
This compliant solution both declares the published
field volatile and reduces its accessibility to package-private so that callers outside the current package scope cannot obtain the this
reference.
Code Block | ||
---|---|---|
| ||
final class Publisher {
static volatile Publisher published;
int num;
Publisher(int number) {
// Initialization
this.num = number;
// ...
published = this;
}
}
|
The constructor publishes the this
reference after initialization has concluded. However, the caller that instantiates Publisher
must ensure that it cannot see the default value of the num
field before it is initialized; to do otherwise would violate TSM03-J. Do not publish partially initialized objects. Consequently, the field that holds the reference to Publisher
might need to be declared volatile in the caller.
Initialization statements may be reordered when the published
field is not declared volatile. The Java compiler, however, forbids declaring fields as both volatile and final.
The class Publisher
must also be final; otherwise, a subclass can call its constructor and publish the this
reference before the subclass's initialization has concluded.
Compliant Solution (Public Static Factory Method)
This compliant solution eliminates the internal member field and provides a newInstance()
factory method that creates and returns a Publisher
instance:
Code Block | ||
---|---|---|
| ||
final class Publisher {
final int num;
private Publisher(int number) {
// Initialization
this.num = number;
}
public static Publisher newInstance(int number) {
Publisher published = new Publisher(number);
return published;
}
}
|
This approach ensures that threads cannot see an inconsistent Publisher
instance. The num
field is also declared final, making the class immutable and consequently eliminating the possibility of obtaining a partially initialized object.
Noncompliant Code Example (Handlers)
This noncompliant code example defines the ExceptionReporter
interface:
Code Block | ||
---|---|---|
Code Block | ||
| ||
// Interface ExceptionReporter public interface ExceptionReporter { public void setExceptionReporter(ExceptionReporter er); public void report(Throwable exception); } |
This interface is implemented by the DefaultExceptionReporter
class, which reports exceptions after filtering out any sensitive information (see ERR00-J. Do not suppress or ignore checked exceptions for more information).
The DefaultExceptionReporter
constructor prematurely publishes the this
reference before construction of the object has concluded. This occurs in the last statement of the constructor (er.setExceptionReporter(this)
), which sets the exception reporter. Because it is the last statement of the constructor, this may be misconstrued as benign.
Code Block | ||
---|---|---|
| ||
// Class ExceptionReportersDefaultExceptionReporter public class ExceptionReportersDefaultExceptionReporter implements ExceptionReporter { public ExceptionReportersDefaultExceptionReporter(ExceptionReporter er) { // Carry out initialization // Incorrectly publishes the "this" reference er.setExceptionReporter(this); } public void report(Throwable exception) { /* default implementation */ } Implementation of public final void setExceptionReporter(ExceptionReporter er) and report() } |
The MyExceptionReporter
class subclasses DefaultExceptionReporter
with the intent of adding a logging mechanism that logs critical messages before reporting an exception.
Code Block | ||
---|---|---|
| ||
{ // Sets the reporter } } // Class MyExceptionReporter derives from ExceptionReportersDefaultExceptionReporter public class MyExceptionReporter extends ExceptionReportersDefaultExceptionReporter { private final Logger logger; public MyExceptionReporter(ExceptionReporter er) { super(er); // Calls superclass's constructor // Obtain the default logger logger = Logger.getLogger("com.organization.Log"); } public void report(Throwable t) { logger.log(Level.FINEST,"Loggable exception occurred", t); } } |
Compliant Solution
The MyExceptionReporter
constructor invokes the DefaultExceptionReporter
superclass's constructor (a mandatory first step), which publishes the exception reporter before the initialization of the subclass has concluded. Note that the subclass initialization consists of obtaining an instance of the default logger. Publishing the exception reporter is equivalent to setting it to receive and handle exceptions from that point on.
Logging will fail when an exception occurs before the call to Logger.getLogger()
in the MyExceptionReporter
subclass because dereferencing the uninitialized logger
field generates a NullPointerException
, which could itself be consumed by the reporting mechanism without being logged.
This erroneous behavior results from the race condition between an oncoming exception and the initialization of MyExceptionReporter
. If the exception arrives too soon, it will find the MyExceptionReporter
object in an inconsistent state. This behavior is especially counterintuitive because logger
has been declared final, so observing an uninitialized value would be unexpected.
Premature publication of an event listener causes a similar problem; the listener can receive event notifications before the subclass's initialization has finished.
Compliant Solution
Rather than publishing the this
reference from the DefaultExceptionReporter
constructor, this compliant solution adds a publishExceptionReporter()
method to DefaultExceptionReporter
to permit setting the exception reporter. This method can be invoked on a subclass instance after the subclass's initialization has concludedThis compliant solution declares the setReporter()
method in class MyExceptionReporter
. It explicitly calls the superclass's setExceptionReporter()
method, publishing a reference to its own Class
object. It is not permissible to publish the reference in the constructor for MyExceptionReporter
for reasons noted earlier in the noncompliant code example.
Code Block | ||
---|---|---|
| ||
public class MyExceptionReporter extends ExceptionReportersDefaultExceptionReporter implements ExceptionReporter { public DefaultExceptionReporter(ExceptionReporter er) { // ... } // Should be called after subclass's initialization is over public void setReporterpublishExceptionReporter(ExceptionReporter er) { super.setExceptionReporter(this); // Registers this exception reporter } // Implementation of setExceptionReporter() and report() } |
In general, detect cases where the this
reference can leak out beyond the scope of the current context. In particular, be careful when using public
variables and methods.
Noncompliant Code Example
Wiki Markup |
---|
It is possible for the {{this}} reference to implicitly get leaked outside the scope \[[Goetz 02|AA. Java References#Goetz 02]\]. Consider inner classes that maintain a copy of the {{this}} reference of the outer object. |
The MyExceptionReporter
subclass inherits the publishExceptionReporter()
method. Callers that instantiate MyExceptionReporter
can use the resulting instance to set the exception reporter after initialization is complete.
Code Block | ||
---|---|---|
| ||
// Class MyExceptionReporter derives from DefaultExceptionReporter
public class MyExceptionReporter extends DefaultExceptionReporter {
private final Logger logger;
public MyExceptionReporter(ExceptionReporter er) {
super(er); // Calls superclass's constructor
logger = Logger.getLogger("com.organization.Log");
}
// Implementations of publishExceptionReporter(),
// setExceptionReporter() and report()
// are inherited
}
|
This approach ensures that the reporter cannot be set before the constructor has fully initialized the subclass and enabled logging.
Noncompliant Code Example (Inner Class)
Inner classes maintain a copy of the this
reference of the outer object. Consequently, the this
reference could leak outside the scope [Goetz 2002]. This noncompliant code example uses a different implementation of the DefaultExceptionReporter
class. The constructor uses an anonymous inner class to publish an exception reporterIn this noncompliant code example, the constructor for class BadExceptionReporter
uses an anonymous inner class to publish a filter()
method. The problem occurs because the this
reference of the outer class is published by the inner class so that other threads can see it. If the class is subclassed, the issue described in the first noncompliant code example resurfaces.
Code Block | ||
---|---|---|
| ||
public class BadExceptionReporterDefaultExceptionReporter implements ExceptionReporter { public BadExceptionReporterDefaultExceptionReporter(ExceptionReporter er) { er.setExceptionReporter(new ExceptionReportersExceptionReporter(er) { public void report(Throwable t) { filter(t); } }); } public void filter(Throwable t) { // Filters sensitive exceptions } // report exception } public void reportsetExceptionReporter(ThrowableExceptionReporter exceptioner) { // Default implementation register ExceptionReporter } public void setExceptionReporter(ExceptionReporter er) { }); } // SetsDefault theimplementations reporterof setExceptionReporter() and }report() } |
Other threads can see the this
reference of the outer class because it is published by the inner class. Furthermore, the issue described in the noncompliant code example for handlers will resurface if the class is subclassed.
Compliant Solution
A {{private}} constructor alongside a {{public}} factory method may be used when it is desired to publish the {{filter()}} method from within the constructor. \[[Goetz 06|AA. Java References#Goetz 06]\]Use a private constructor and a public static factory method to safely publish the exception reporter from within the constructor [Goetz 2006a]: Wiki Markup
Code Block | ||
---|---|---|
| ||
public class GoodExceptionReporterDefaultExceptionReporter implements ExceptionReporter { private final ExceptionReportersExceptionReporter erdefaultER; private GoodExceptionReporterDefaultExceptionReporter(ExceptionReporter excr) { erdefaultER = new ExceptionReportersExceptionReporter(excr) { public void report(Throwable t) { // Report exception } filter(t); public void setExceptionReporter(ExceptionReporter er) { // Register ExceptionReporter } }; } public static GoodExceptionReporterDefaultExceptionReporter newInstance( ExceptionReporter excr) { GoodExceptionReporterDefaultExceptionReporter gerder = new GoodExceptionReporterDefaultExceptionReporter(excr); excr.setExceptionReporter(gerder.erdefaultER); return gerder; } public void filter(Throwable t) { } // Default implementations of setExceptionReporter() and report() } |
Because the constructor is private, untrusted code cannot create instances of the class; consequently, the this
reference cannot escape. Using a public static factory method to create new instances also protects against untrusted manipulation of internal object state and publication of partially initialized objects (see TSM03-J. Do not publish partially initialized objects for additional information).
Noncompliant Code Example (Thread)
This noncompliant code example starts a thread inside the constructor:
Code Block | ||
---|---|---|
| ||
final class ThreadStarter implements Runnable { public void report(Throwable exceptionThreadStarter() { } public void setExceptionReporter(ExceptionReporter er) { } } |
Noncompliant Code Example
Wiki Markup |
---|
This noncompliant code example starts a thread from within the constructor. This allows the new thread to access the {{this}} reference of the current object. \[[Goetz 02|AA. Java References#Goetz 02]\] and \[[Goetz 06|AA. Java References#Goetz 06]\] |
Thread thread = new Thread(this);
thread.start();
}
@Override public void run() {
// ...
}
}
|
The new thread can access the this
reference of the current object [Goetz 2002], [Goetz 2006a]. Notably, the Thread()
constructor is alien to the ThreadStarter
class.
Compliant Solution (Thread)
This compliant solution creates and starts the thread in a method rather than in the constructor:
Code Block | ||
---|---|---|
| ||
final class ThreadStarter implements Runnable {
public void startThread() {
Thread | ||
Code Block | ||
| ||
public someConstructor() { thread = new MyThreadThread(this); thread.start(); } |
Compliant Solution
@Override public void run() {
// ...
}
}
|
Exceptions
TSM01-J-EX0: It is safe to create a thread in the constructor, provided the thread is not started until after object construction is complete, because a call to start()
on a thread happens-before any actions in the started thread [JLS 2015].
Even though this code example creates a thread that references this
in the constructor, the thread is started only when its start()
method is called from the startThread()
method [Goetz 2002], [Goetz 2006a]. In this compliant solution, even though the thread is created in the constructor, it is not started unless the {{start()}} method is called from somewhere other than the constructor. This behavior is permissible. \[[Goetz 02|AA. Java References#Goetz 02]\] and \[[Goetz 06|AA. Java References#Goetz 06]\] Wiki Markup
Code Block | ||
---|---|---|
| ||
final class ThreadStarter implements Runnable { Thread thread; public someConstructorThreadStarter() { thread = new MyThreadThread(this); } public void startstartThread() { thread.start(); } @Override public void run() { // ... } } |
TSM01-J-EX1: Use of the ObjectPreserver
pattern [Grand 2002] described in TSM02-J. Do not use background threads during class initialization is safe and is permitted.
Risk Assessment
Allowing the this
reference to escape may can result in improper initialization and runtime exceptions. The problem is aggravated if the class is sensitive.
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
---|
TSM01-J |
Medium |
Probable |
High | P4 | L3 |
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]\] Keyword "this"
\[[Goetz 02|AA. Java References#Goetz 02]\]
\[[Goetz 06|AA. Java References#Goetz 06]\] 3.2. Publication and Escape |
Tool | Version | Checker | Description | ||||||
---|---|---|---|---|---|---|---|---|---|
Parasoft Jtest |
| CERT.TSM01.CTRE | Do not let "this" reference escape during construction |
Bibliography
Section 3.2, "Publication and Escape" | |
Chapter 5, "Creational Patterns, Singleton" | |
[JLS 2015] | §15.8.3, "this " |
Issue Tracking
Tasklist | ||||
---|---|---|---|---|
| ||||
||Completed||Priority||Locked||CreatedDate||CompletedDate||Assignee||Name||
|T|M|F|1270219843973|1270221864972|svoboda|"*Inner classes* implicitly hold a reference to the instance of the outer class, unless the inner class is declared as static." => Change inner classes to "An inner class implicitly holds ... "|
|T|M|F|1270220129871|1270755934790|rcs|"Note that this code also violates CON32-J. Protect accessible mutable static fields from untrusted code" => Not sure if I agree because the class is package-private and inaccessible to untrusted code|
|T|M|F|1270733657099|1271021912028|rcs_mgr|"A Runnable object's constructor may construct a Thread object around itself, as long as the thread is not actually started in the Runnable object's constructor." => I still think this info is redundant.|
|
...
CON39-J. Ensure atomicity of 64-bit operations 11. Concurrency (CON) 11. Concurrency (CON)