According to the The Java Language Specification \[[JLS 05|AA. Java References#JLS 05]\], section 15, §15.8.3 {{this}}, "Wiki Markup " [JLS 2015]:this
When used as a primary expression, the keyword
thisdenotes 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
thisis the classCor interface type T within which the keywordthisoccurs. At ...At run time, the class of the actual object referred to may be the class
Cor any subclass ofCT, 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
(possiblythisfrom a nonprivatefinal) method, overridable method that is invoked from the constructor of
an object under construction- Passing
thisas an argument to an alien method invoked from the constructor of an object under construction. - Publishing
thisusingpublic staticvariables from the constructor of an object under construction - Calling a non-final method from a constructor (MET04-J.
a class whose object is being constructed (for more information, see MET05-J. Ensure that constructors do not call overridable methods)
- Overriding the finalizer of a non-final class and obtaining the
thisreference of a partially initialized instance, when the construction of the object ceases (OBJ04-J. Do not allow partially initialized objects to be accessed). This usually happens when the constructor throws exceptions. Trusted code may also add a finalizer and letthisescape by violating OBJ08-J. Avoid using finalizers. - Passing internal object state to an alien method. This enables the method to retrieve the
thisreference of the internal object.
This guideline focuses on the potential consequences of this escaping during object construction including race conditions and improper initialization. For example, declaring a field final ensures that all threads will see it fully initialized only when the this reference does not escape during the corresponding object's construction. The guideline CON26-J. Do not publish partially initialized objects discusses the guarantees provided by various mechanisms for safe publication and relies on conformance to this guideline. In general, it is important to detect cases where 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.
.
- Returning
thisfrom 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
thisas 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
thisto 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
thisreference 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; | ||
| Code Block | ||
| ||
class Publisher { public static volatile Publisher pub; // Also noncompliant if field is nonvolatile int num; Publisher(int number) { pubpublished = this; // Initialization this.num = number; // ... } } |
Consequently, other threads may obtain a partially initialized Publisher instance. Also, if the object initialization (and consequently, its construction) If an object's initialization (and consequently, its construction) depends on a security check within the constructor, the security check will can be bypassed if when an untrusted caller obtains the partially initialized instance (see OBJ04OBJ11-J. Do not allow partially initialized objects to be accessed for more detailsBe 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 but is still . It remains vulnerable because the field pub is not declared volatile and has public accessibility published field has public accessibility and the programmer has failed to declare it as volatile.
| Code Block | ||
|---|---|---|
| ||
final class Publisher { public static Publisher pubpublished; int num; Publisher(int number) { // Initialization this.num = number; // ... pubpublished = 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 noncompliant code example compliant solution both declares the pub published field as volatile and reduces the its accessibility of the static class field to package-private so that untrusted callers beyond outside the current package scope cannot obtain the this reference.
| Code Block | ||
|---|---|---|
| ||
final class Publisher { static volatile Publisher pubpublished; int num; Publisher(int number) { // Initialization this.num = number; // ... pubpublished = this; } } |
The constructor publishes the this reference after initialization has concluded. However, the caller which that instantiates Publisher, must ensure that it does not cannot see the default value of the num field , before it is initialized (a violation of CON26; to do otherwise would violate TSM03-J. Do not publish partially initialized objects). Consequently, the field that holds the reference to Publisher may might need to be declared volatile in the caller.
If the pub Initialization statements may be reordered when the published field is not declared as volatile initialization statements may be reordered. The Java compiler does not allow declaring the static pub field as final in this case, however, forbids declaring fields as both volatile and final.
The class Publisher should must also be final; otherwise, otherwise a subclass might execute can call its constructor and consequently, publish the this reference before the subclass's initialization has concluded.
Compliant Solution (
...
Public Static Factory Method)
This compliant solution removes eliminates the internal member field and provides a newInstance() factory method which can be used to obtain an instance of the Publisher object. 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 pupublished = new Publisher(number); return pupublished; } } |
This approach ensures that threads do not see a compromised cannot see an inconsistent Publisher instance. The num field is also declared as final, which makes making the class immutable. Consequently, there is no threat of a caller invoking newInstance() to obtain 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 |
|---|
public interface ExceptionReporter {
public void setExceptionReporter(ExceptionReporter er);
public void report(Throwable exception);
}
|
that This interface is implemented by the class DefaultExceptionReporter. This class is useful for reporting class, which reports exceptions after filtering out any sensitive information (EXC01see ERR00-J. Use a class dedicated to reporting exceptionsDo 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 DefaultExceptionReporter public class DefaultExceptionReporter implements ExceptionReporter { public DefaultExceptionReporter(ExceptionReporter er) { // Carry out initialization // Incorrectly publishes the "this" reference er.setExceptionReporter(this); } // Implementation of setExceptionReporter() and report() } |
The MyExceptionReporter class MyExceptionReporter subclasses DefaultExceptionReporter with the intent of adding a logging mechanism that logs critical messages before reporting an exception is reported.
| 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// = Obtain the default logger logger = Logger.getLogger("com.organization.Log"); // Obtain the default logger } public void report(Throwable t) { logger.log(Level.FINEST,"Loggable exception occurred", t); } } |
Its The MyExceptionReporter constructor invokes the DefaultExceptionReporter superclass DefaultExceptionReporter'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 so that it can to receive and handle exceptions from that point onwardson.
If any Logging will fail when an exception occurs before the call to Logger.getLogger() in the subclass MyExceptionReporter, it is not logged. Instead, a NullPointerException is generated which may 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 comes arrives too soon, it finds will find the MyExceptionReporter object in a compromised an inconsistent state. This behavior is especially counter intuitive counterintuitive because logger is has been declared final and is not expected to contain an unintialized value. , so observing an uninitialized value would be unexpected.
Premature publication of an event listener causes a similar problem; the listener can receive event notifications This issue can also occur when an event listener is prematurely published. Consequently, it will start receiving event notifications even before the subclass's initialization has concludedfinished.
Compliant Solution
Instead of Rather than publishing the this reference from the DefaultExceptionReporter constructor, this compliant solution uses the setExceptionReporteradds a publishExceptionReporter() method of to DefaultExceptionReporter to set permit setting the exception reporter. This method can be invoked on a subclass instance , after the subclass's initialization has concluded.
| Code Block | ||
|---|---|---|
| ||
// Class DefaultExceptionReporter public class DefaultExceptionReporter implements ExceptionReporter { public DefaultExceptionReporter(ExceptionReporter er) { // ... } // Should be called after subclass's initialization is over public final void setExceptionReporterpublishExceptionReporter() { setExceptionReporter(this); // Registers this exception reporter } // Implementation of setExceptionReporter() and report() } |
The MyExceptionReporter subclass MyExceptionReporter inherits the setExceptionReporterpublishExceptionReporter() method and a caller who instantiates . Callers that instantiate MyExceptionReporter can use its the resulting instance to set the exception reporter , after initialization is overcomplete.
| 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 has been enabled.
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 reporter.
| Code Block | ||
|---|---|---|
| ||
public class DefaultExceptionReporter implements ExceptionReporter {
public DefaultExceptionReporter(ExceptionReporter er) {
er.setExceptionReporter(new ExceptionReporter() {
public void report(Throwable t) {
// report exception
}
|
| 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. This noncompliant code example uses a different implementation of class {{DefaultExceptionReporter}}. The constructor uses an anonymous inner class to publish a {{filter()}} method. |
| Code Block | ||
|---|---|---|
| ||
public class DefaultExceptionReporter implements ExceptionReporter { public DefaultExceptionReporter(ExceptionReporter er) { er.setExceptionReporter(new DefaultExceptionReporter(er) { public void reportsetExceptionReporter(ThrowableExceptionReporter ter) { // register filter(t);ExceptionReporter } }); } // Default implementations of setExceptionReporter() and report() } |
The Other threads can see the this reference of the outer class because it is published by the inner class so that other threads can see it. Furthermore, if the class is subclassed, the issue described in the previous noncompliant code example resurfacesfor handlers will resurface if the class is subclassed.
Compliant Solution
A {{private}} constructor alongside a {{public static}} factory method can be used to safely 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 DefaultExceptionReporter implements ExceptionReporter { private final DefaultExceptionReporterExceptionReporter defaultER; private DefaultExceptionReporter(ExceptionReporter excr) { defaultER = new DefaultExceptionReporterExceptionReporter(excr) { public void report(Throwable t) { // Report filter(t);exception } }; } public void public setExceptionReporter(ExceptionReporter er) { // Register ExceptionReporter } }; } public static DefaultExceptionReporter newInstance( ExceptionReporter excr) { DefaultExceptionReporter der = new DefaultExceptionReporter(excr); excr.setExceptionReporter(der.defaultER); return der; } // Default implementations of setExceptionReporter() and report() } |
Because the constructor is private, untrusted code cannot create instances of the class; consequently, prohibiting the this reference from escapingcannot 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 (CON26see TSM03-J. Do not publish partially initialized objects for additional information).
Noncompliant Code Example (
...
Thread)
This noncompliant code example starts a thread from within inside the constructor. :
| Code Block | ||
|---|---|---|
| ||
final class ThreadStarter implements Runnable { public ThreadStarter() { Thread thread = new Thread(this); thread.start(); } @Override public void run() { // ... } } |
| Wiki Markup |
|---|
This allows the new thread to access the {{this}} reference of the current object \[[Goetz 02|AA. Java References#Goetz 02]\], \[[Goetz 06|AA. Java References#Goetz 06]\]. Notably, the constructor {{Thread()}} is [alien|BB. Definitions#alien method] to the class {{ThreadStarter}}. |
...
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 instead of rather than in the constructor. :
| Code Block | ||
|---|---|---|
| ||
final class ThreadStarter implements Runnable { public ThreadStarter() { // ... } public void startThread() { Thread thread = new Thread(this); thread.start(); } @Override public void run() { // ... } } |
Exceptions
unmigratedTSM01-wiki-markup
*CON14:EX1*: In this exception, even though a thread referencing {{this}} is created in the constructor, it is not started until its {{start()}} method is called from method {{startThread()}} \[[Goetz 02|AA. Java References#Goetz 02]\], \[[Goetz 06|AA. Java References#Goetz 06]\].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].
| Code Block | ||
|---|---|---|
| ||
final class ThreadStarter implements Runnable { Thread thread; public ThreadStarter() { thread = new Thread(this); } public void startThread() { thread.start(); } @Override public void run() { // ... } } |
unmigratedTSM01-wiki-markup
It is safe to create the thread in the constructor as long as it is not started until object construction is over. This is because "A call to start() on a thread happens-before any actions in the started thread." \[[JLS 05|AA. Java References#JLS 05]\]. However, this approach may incur more maintainability costs.| Wiki Markup |
|---|
The {{ObjectPreserver}} pattern, based on \[[Patterns 02|AA. Java References#Patterns 02]\]), and described in Exception 1 of [CON03-J. Do not use background threads during class initialization] is another example of code that safely violates this guideline. |
Risk Assessment
Allowing the this reference to escape may result in improper initialization and runtime exceptions.
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
|---|---|---|---|---|---|
CON14-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
\[[Patterns 02|AA. Java References#Patterns 02]\] Chapter 5, Creational Patterns, Singleton |
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 can result in improper initialization and runtime exceptions.
Rule | Severity | Likelihood | Detectable | Repairable | Priority | Level |
|---|---|---|---|---|---|---|
TSM01-J | Medium | Probable | Yes | No | P8 | L2 |
Automated Detection
| 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.|
|
...
VOID CON14-J. Ensure atomicity of 64-bit operations 11. Concurrency (CON) 11. Concurrency (CON)