Writing secure Java code

Below are some of my recommendations on writing secure Java code. - BL Access Guidelines By default, set access for class variable and methods to private. Revise the access (public, protected, etc.) as justified and documented. In general, favor keeping class variables as private and using accessor methods - e.g. getVariable() and setVariable(). Favor a minimulist set of methods as public - just enough to implement the responsibilities of the class - and keep any methods which implement the internal workings of the class behavior as private. By default, set make all class variables and methods as final. Revise this as justified and documented. In general, class variables and accessor methods - getVariable() and setVariable() - should remain final. By default, keep class methods as final unless the class hierarchy design specifically permits removing the finalkeyword. Remove final on class methods only as a deliberate, justified, and documented decision. Add a private boolean variable called "initialized" to each class. By default, the value of initialized should be false. Have each construtor set the initialized to true as the last statement of the constructor - i.e. only if the constructor doesn't throw an exception. If the class has a static initializer, i.e. a "factory", ensure that this initializer also sets the initialized variable on any objects it initializes as its last statement. Have each non-constructor method of the class check the initialized variable as its first statement. Use the default package accessibility for classes, methods and variables only when justified and documented. Avoid the default package accesiblity and favor explicitly marking the visibility - private, protected, etc. As already noted, also favor using the minimum accessibility necessary to implement the responsibilities of the class. Do not use inner classes unless justified and documented. Favor using other constructs such as adaptors, decorators, or some other class design instead of inner classes. Most compilers translate inner classes into classes with package visbility and silently makes the contents of the outer class as package scope as well - this not only increases the exposure of code but (silently!) over-rides your use of private while doing so. Do not store keying (e.g. cryptographic keys) or other sensitive information in your code. This information will be exposed to the JVM and vulnerable to attack or accidental disclosure. Don't store keying or other sensitive information in your code even if you are using a code obfuscator - a determined attacker may still be able to undo the obfuscation and read this information. Use the package.definition property in the java.security file to explicitly define the contents of your packages. Alternatively, put your packaged classes into a sealed JAR file. Either helps prevent errant or malicious code from being inserted into your package namespace. Use the package.access property to explicicitly grant (or restrict) access to the classes in your package. This prevents untrusted code, errant or malicious, from gaining access to your code. Signing and Privileged Code By default, keep your code unsigned [sic]. Code that is unsigned will run without any special privileges and users of your unsigned code are less likely to be harmed by your code. If you must produce signed code, ensure that the need (and risk) for this justified amd documented - also that this code is audited and tested appropriately. Place your signed and unsigned code into separate archive files. This helps protect the software system from errors and attacks. Use signing properties in your classes. Provide and consume code-signing mechanisms that allow classes to be interrogated for signing properties. For example, include in your classes a public final version stamp variable, to help users of your classes (including your own code) at run-time they are using the correct code. By default, do not write privileged code. When used, use as sparingly as possible. Minimize the number of lines of code that are privileged. Minimize the scope that is privileged. . Minimize the accessibility (public, protected, private, etc.) of the privileged code. Cloning and Serialization By default, make your classes non-cloneable. Allow your classes to implement the java.lang.Cloneable interface only when the need has been justified and documented. This will prevent malicious or errant code from corrupting the system thru the cloned classes. By default, make cloneable classes have a clone() method that is final. If a cloneable class is justified, this prevents malicious or errant code from from corrupting the system by re-defining the clone() method. By default, make classes non-serializeable and non-desializeable. This prevents errant or malicious code from corrupting the system thru manipulating the serialized or de-serialized contents of an object. Ensure that the writeObject() and readObject() methods are not only re-defined to not perform these operations (and to throw exceptions if called) but that they are marked as final to prevent them from being re-defined again to permit serialization or de-serialization. If your class must be serializeable, ensure that the byte streams are encrypted. Safe Comparisons Compare classes using equality operator ("==") comparison and not by name. Comparisons by name are unreliable as most JVMs will permit multiple classes with the same name. Comparison by name can allow errant or malicious code to corrupt the system. Use the equality operator and don't rely upon the an .equals() method as those results are less reliable. Using Immutable Objects Create and use immutable objects whenever possible. This prevents data in the objects from being accidentally or maliciously corrupted. It also improves performance (since locking isn't required for these objects). For data objects returned from your code (e.g. the return values of public methods) which can't be made immutable, then make them cloneable (with appropriate safeguards) and have your methods return the cloned copy - keeping the original for use within your code. For example, standard Java data structures such as Vectors, Hashtables, etc. are not immutable and better returned as clones. When returning an aggregate data structure like an array, be sure to clone the array contents and not just the array reference.

No comments: