...
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.
...
| Code Block | ||
|---|---|---|
| ||
// Interface ExceptionReporter
public interface ExceptionReporter {
public void setExceptionReporter(ExceptionReporter er);
public void report(Throwable exception);
}
// Class ExceptionReporters
public class ExceptionReporters implements ExceptionReporter {
public ExceptionReporters(ExceptionReporter er) {
// Carry out initialization
// Incorrectly publishes the "this" reference
er.setExceptionReporter(this);
}
public void report(Throwable exception) { /* default implementation */ }
public final void setExceptionReporter(ExceptionReporter er) {
// Sets the reporter
}
}
// Class MyExceptionReporter derives from ExceptionReporters
public class MyExceptionReporter extends ExceptionReporters {
private final Logger logger;
public MyExceptionReporter(ExceptionReporter er) {
super(er); // Calls superclass's constructor
logger = Logger.getLogger("com.organization.Log");
}
public void report(Throwable t) {
logger.log(Level.FINEST,"Loggable exception occurred",t);
}
}
|
Compliant Solution
This 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.
...
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. |
...
| Code Block | ||
|---|---|---|
| ||
public class BadExceptionReporter implements ExceptionReporter {
public BadExceptionReporter(ExceptionReporter er) {
er.setExceptionReporter(new ExceptionReporters(er) {
public void report(Throwable t) {
filter(t);
}
});
}
public void filter(Throwable t) {
// Filters sensitive exceptions
}
public void report(Throwable exception) {
// Default implementation
}
public void setExceptionReporter(ExceptionReporter er) {
// Sets the reporter
}
}
|
Compliant Solution
| Wiki Markup |
|---|
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]\] |
| Code Block | ||
|---|---|---|
| ||
public class GoodExceptionReporter implements ExceptionReporter {
private final ExceptionReporters er;
private GoodExceptionReporter(ExceptionReporter excr) {
er = new ExceptionReporters(excr) {
public void report(Throwable t) {
filter(t);
}
};
}
public static GoodExceptionReporter newInstance(ExceptionReporter excr) {
GoodExceptionReporter ger = new GoodExceptionReporter(excr);
excr.setExceptionReporter(ger.er);
return ger;
}
public void filter(Throwable t) { }
public void report(Throwable exception) { }
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]\] |
| Code Block | ||
|---|---|---|
| ||
public someConstructor() {
thread = new MyThread(this);
thread.start();
}
|
Compliant Solution
| Wiki Markup |
|---|
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]\] |
| Code Block | ||
|---|---|---|
| ||
public someConstructor() {
thread = new MyThread(this);
}
public void start() {
thread.start();
}
|
Risk Assessment
Allowing the this reference to escape may result in improper initialization and runtime exceptions. The problem is aggravated if the class is sensitive.
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
|---|---|---|---|---|---|
CON40-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 |
...