When you declare a variable final, you do not want anyone to change it. If the type of variable is primitive types, you can undoubtedly make it. Unfortunately, if the variable is a reference to an object, the "final" stuff you think may be not final!
Non-compliant Code Example
Code Block |
---|
class Test{ Â Â Test(int a, int b){ Â Â this.a = a; Â Â this.b = b; Â } Â void set_ab(int a, int b){ Â Â this.a = a; Â Â this.b = b; Â } Â void print_ab(){ Â Â System.out.println("the value a is: "+this.a); Â Â System.out.println("the value b is: "+this.b); Â } Â private int a; Â private int b; } public class TestFinal1 { Â Â public static void main(String[] args) { Â Â Â Â Â Â Â final Test mytest = new Test(1,2); Â Â Â Â Â Â Â mytest.print_ab(); Â Â Â Â Â Â Â //now we change the value of a,b. Â Â Â Â Â Â Â mytest.set_ab(5, 6); Â Â Â Â Â Â Â mytest.print_ab(); Â Â Â Â Â Â Â Â Â Â } } |
We can see that the value of a and b has been changed, which means that when you declare a reference final, it only means that the reference can not be changed but the contents it refer to can still be changed!
Non-Compliant Solution
If you do not want to change a and b after they are initialized, the simplest approach is to declare a and b final:
...
But now you can not have setter methods of a and b.
Compliant Solution
An alternative approach is to provide the clone method in the class. When you want do something about the object, you can use clone method to get a copy of original object. Now, you can do everything to this new object, and the original one will be never changed.
...
One common mistake about this is to use public static final array, clients will be able to modify the contents of the array (although they will not be able to change the array itself, as it is final).
Non-compliant Code Example
Code Block |
---|
 public static final SomeType [] SOMETHINGS = { ... }; |
Wiki Markup |
---|
With this declaration, {{SOMETHINGS\[1\]}}, etc. can be modified by clients of the code. |
Compliant Solution
One approach is to make use of above method: first define a private array and then provide a public method that returns a copy of the array:
...
Now, the original array values cannot be modified by a client.
Compliant Solution 2
An alternative approach is to have a private array from which a public immutable list is contructed:
...
Now, neither the original array values nor the public list can be modified by a client.
Risk Assessment
Using final to declare the reference to an object is a potential security risk, because the contents of the object can still be changed.
Recommendation | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
OBJ03-J | medium | likely | medium | P9 | L2 |
Automated Detection
TODO
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
References
Chapter 6, Core Java⢠2 Volume I - Fundamentals, Seventh Edition by Cay S. Horstmann, Gary Cornell
...