To kickstart the new year and in an attempt to get more writing done I think I'll try writing some shorter bits. This one's about the Java "final" keyword - it's different nuances and how they relate to security.
Final has meanings that are so distinct that I sometimes wonder if it wouldn't have been clearer to use several different keywords. Here are the meanings of the keyword final:
Final classesClasses with the modifier final cannot be subclassed. If the instances of the class have a state, that state can change, static fields, etc, everything may be mutable. The final here only prohibits subclassing.
Final methodsMethods with the modifier final cannot be overwritten/overridden by subclasses. The methods can be used by subclasses, their output may differ from call to call, they just cannot be redefined in the subclasses. The method may be overloaded, because overloaded methods (methods with the same name, but different signature) are completely different methods in the eyes of the compiler and the runtime.
Final fieldsThe value for fields with the modifier final can only be set once.
In the case of primitive type fields, this means that if the value was set to (int) 91, then the value will remain 91. The compiler may take advantage of this knowledge and inline the value where it is being referred.
In the case of objects, if the field is set to reference an object, it will always reference that same object. If the object is mutable, the perceived and logical value of the object may change, only it's identity is guaranteed not to change.
Final method variablesSince method variables aren't accessible outside the method, the final keyword here is only for use of the compiler.
Security and finalHere's how these nuances of the final keyword relate to security:
ClassesFinal classes are very restrictive; since you can't subclass them you can't make them Serializable and you can't override their functionality. As far as I can tell, there is no way around it either, the rule is absolute: if it's final, you can't override it.
MethodsFinal methods, like the classes are very restrictive. At the most, you may be able to override another method that the final method calls and use that to alter the method's functioning.
FieldsFinal fields are not such an obvious case; while you cannot redefine their value there are some interesting details about them.
Their value isn't always the same. If you can obtain access to an object before it's initializer has defined the value of the final field, the field will have it's uninitialized value which will be 0, false or null for numeric types, boolean types and object types respectively. Then once the initializer sets the value it will change to the defined value. That's a very minor detail, but security is all about knowing all the right minor details.
As stated, the field will always reference the same object, but the real value of that object is free to change. If the object contains fields, etc that can be accessed and whose value can be altered then the value of the object itself can be changed.
Arrays are a special type of mutable objects -- the array elements of a final array field can change. The array object itself will stay the same, and it's size or number of dimensions cannot change, but the element values are very much mutable.
A multidimensional array object is actually an array of objects with one less dimensions. Thus in the case of a final multidimensional array object, only the outermost array is really final; the inner arrays may change identity and size.
sun.misc.UnsafeThe reflection API is bound by the final keyword and if you try changing the value of a final field via reflection, you will run into an IllegalAccessException.
There is, however, one omnipotent class in the sun.misc package, called Unsafe, which directly write into memory, put int values into object fields and it is also able to rewrite values into final fields. You use the fieldOffset methods to determine the offset of a given field, and then you use one of the putXXX methods to set the value. Unsafe can also access private fields.