Difference between revisions of "Java leading security practice"

From OWASP
Jump to: navigation, search
m (Added navigation to facilitate sequential reading online)
 
(7 intermediate revisions by 2 users not shown)
Line 1: Line 1:
[[OWASP Code Review Guide Table of Contents]]__TOC__
+
{{LinkBar
 +
  | useprev=PrevLink | prev=Java Gotchas | lblprev=
 +
  | usemain=MainLink | main=OWASP Code Review Guide Table of Contents | lblmain=Table of Contents
 +
  | usenext=NextLink | next=Classic ASP Design Mistakes | lblnext=
 +
}}
 +
__TOC__
  
 
==Introduction==
 
==Introduction==
This section covers the main Java-centric areas which are prescribed as leading security practices when developing Java applications and code. So when we are performing a code review on Java code we should look at the following areas of concern. Getting developers to adopt leading practice techniques gives the inherent basic security features all code should have, "Self Defending Code".
+
This section covers the main Java-centric areas which are prescribed as leading security practices when developing Java applications and code. When we are performing a code review on Java code, we should look at the following areas of concern. Getting developers to adopt leading practice techniques gives the inherent basic security features all code should have, "Self Defending Code".  
 
+
 
+
  
 
===Class Access===
 
===Class Access===
Line 11: Line 14:
 
#Mutable Objects
 
#Mutable Objects
  
Put simply, don't have public fields or methods in a class unless required. Every method, field, or class that is not private is a potential avenue of attack. Provide accessors to them so you can limit their accessibility.
+
Put simply, don't have public fields or methods in a class unless required. Every method, field, or class that is not private is a potential avenue of attack. Provide accessors to them so you can limit their accessibility.  
  
 
===Initialisation===
 
===Initialisation===
Allocation of objects without calling a constructor is possible. One does not neet to call a constructor to instantiate an object, so dont rely on initialization as there are many ways to allocate uninitialized objects.
+
Allocation of objects without calling a constructor is possible. One does not need to call a constructor to instantiate an object, so don't rely on initialization as there are many ways to allocate uninitialized objects.  
  
#Get the class to verify that it has been initialized prior to it performing any function.
+
# Get the class to verify that it has been initialized prior to it performing any function. Add a boolean that is set to "TRUE" when initialized; make this private. This can be checked when required by all non-constructor methods.  
Add a boolean that is set to "TRUE" when initialized, make this private. This can be checked when required by all non-constructor methods.
+
# Make all variables private and use setters/getters.  
#Make all variables private and use setters/getters.
+
# Make static variables private, this prevents access to uninitialized variables.  
#Make static variables private, this prevents access to uninitialized variables.
+
  
 
===Finality===
 
===Finality===
Non-Final classes let an attacker extend a class in a malicious manner. An application may have a USER object which by design would never be extended, so implementing this class as Final would prevent malicious code extending the user class.
+
Non-Final classes let an attacker extend a class in a malicious manner. An application may have a USER object which by design would never be extended, so implementing this class as Final would prevent malicious code extending the user class. Non-final classes should be such for a good reason. Extensibility of classes should be enabled if it is required not simply for the sake of being extensible.  
Non-final classes should be such for a good reason. Extensibility of classes should be enabled if it is required not simply for the sake of being extensible.
+
  
 
===Scope===
 
===Scope===
Package scope is really used so there are no naming conflicts for an application especially when reusing classes from another framework. Packages are by default open, not sealed which means a rogue class can be added to your package.
+
Package scope is really used so there are no naming conflicts for an application, especially when reusing classes from another framework. Packages are by default open, not sealed, which means a rogue class can be added to your package. If such a rogue class was added to a package, the scope of protected fields would not yield any security. By default, all fields and methods not declared public or private are protected, and can only be accessed within the same package; don’t rely on this for security.
If such a rogue class was added to a package the scope of protected fields would not yield any security. By default all fields and methods not declared public or private are protected and can only be accessed within the same package, don’t rely on this for security.
+
  
 
===Inner Classes===
 
===Inner Classes===
Simply put, when translated into bytecode, inner classes are "rebuilt" as external classes in the same package. This means any class in the package can access this inner class. The owner/enclosing/father classes’ private fields are morphed into protected fields as they are accessible by the now external inner class.
+
Simply put, when translated into bytecode, inner classes are "rebuilt" as external classes in the same package. This means any class in the package can access this inner class. The owner/enclosing/father classes’ private fields are morphed into protected fields as they are accessible by the now external inner class.  
  
 
===Hard Coding===
 
===Hard Coding===
Don't hard code any passwords, user ID's, etc in your code. Silly and bad design. Can be decompiled. Place them in a protected directory in the deployment tree.
+
Don't hard code any passwords, user IDs, etc in your code. Silly and bad design. Can be decompiled. Place them in a protected directory in the deployment tree.  
  
 
===Cloneability===
 
===Cloneability===
Override the clone method to make calsses unclonable unless required.  
+
Override the clone method to make classes unclonable unless required. Cloning allows an attacker to instantiate a class without running any of the class constructors. Define the following method in each of your classes:  
Cloning allows an attacker to instantiate a class without running any of the class constructors.  
+
Define the following method in each of your classes:  
+
  
 
  public final Object clone() throws java.lang.CloneNotSupportedException {
 
  public final Object clone() throws java.lang.CloneNotSupportedException {
Line 44: Line 42:
 
   }
 
   }
  
If clone is required one can make ones clone method immune to overriding by using the final keyword:
+
If a clone is required, one can make one’s clone method immune to overriding by using the final keyword:  
 +
 
 
  public final void clone() throws java.lang.CloneNotSupportedException {
 
  public final void clone() throws java.lang.CloneNotSupportedException {
 
   super.clone();
 
   super.clone();
Line 51: Line 50:
  
 
===Serialization/Deserialization===
 
===Serialization/Deserialization===
Serialization can be used to save objects when the JVM is "switched off". Serialization flattens the object and saves it as a stream of bytes.
+
Serialization can be used to save objects when the JVM is "switched off". Serialization flattens the object and saves it as a stream of bytes. Serialization can allow an attacker to view the inner state of an object and even see the status of the private attributes.  
Serialization can allow an attacker to view the inner stste of an object and even see the status of the private attributes.
+
  
To prevent serialization of ones objects the following code can be included in the object.
+
To prevent serialization of one’s objects, the following code can be included in the object.  
  
 
  private final void writeObject(ObjectOutputStream out)
 
  private final void writeObject(ObjectOutputStream out)
Line 61: Line 59:
 
   }
 
   }
  
writeObject() is the method which kicks-off the serialization procedure. by overriding this method to throw an exception and making it final the object can not be serialized.
+
writeObject() is the method which kicks-off the serialization procedure. By overriding this method to throw an exception and making it final, the object cannot be serialized.
 +
 
 +
When Serialization of objects occurs, transient data gets dropped, so "tagging" sensitive information as transient protects against serialization attacks.  
  
When Serialization of objects occurs transient data gets dropped so "tagging" sensitive information as transient protects against serialization attacks.
+
Deserialization can be used to construct an object from a stream of bytes, which may mimic a legitimate class. This could be used by an attacker to instantiate an object’s state. As with object serialization, deserialization can be prevented by overriding its corresponding method call readObject().  
  
Deserialization can be used to construct and object from a stream of bytes which may mimic a ligitimate class. This could be used by an attacker to instantiate an objects state.
 
As with object serialization, deserialization can be prevented by overriding its corresponding method call readObject().
 
  
 
  private final void readObject(ObjectInputStream in)
 
  private final void readObject(ObjectInputStream in)
Line 74: Line 72:
  
  
 +
{{LinkBar
 +
  | useprev=PrevLink | prev=Java Gotchas | lblprev=
 +
  | usemain=MainLink | main=OWASP Code Review Guide Table of Contents | lblmain=Table of Contents
 +
  | usenext=NextLink | next=Classic ASP Design Mistakes | lblnext=
 +
}}
  
 
[[Category:OWASP Code Review Project]]
 
[[Category:OWASP Code Review Project]]
[[Category:Java Leading Practice]]
 

Latest revision as of 11:45, 9 September 2010

«««« Main
(Table of Contents)
»»»»

Contents


Introduction

This section covers the main Java-centric areas which are prescribed as leading security practices when developing Java applications and code. When we are performing a code review on Java code, we should look at the following areas of concern. Getting developers to adopt leading practice techniques gives the inherent basic security features all code should have, "Self Defending Code".

Class Access

  1. Methods
  2. Fields
  3. Mutable Objects

Put simply, don't have public fields or methods in a class unless required. Every method, field, or class that is not private is a potential avenue of attack. Provide accessors to them so you can limit their accessibility.

Initialisation

Allocation of objects without calling a constructor is possible. One does not need to call a constructor to instantiate an object, so don't rely on initialization as there are many ways to allocate uninitialized objects.

  1. Get the class to verify that it has been initialized prior to it performing any function. Add a boolean that is set to "TRUE" when initialized; make this private. This can be checked when required by all non-constructor methods.
  2. Make all variables private and use setters/getters.
  3. Make static variables private, this prevents access to uninitialized variables.

Finality

Non-Final classes let an attacker extend a class in a malicious manner. An application may have a USER object which by design would never be extended, so implementing this class as Final would prevent malicious code extending the user class. Non-final classes should be such for a good reason. Extensibility of classes should be enabled if it is required not simply for the sake of being extensible.

Scope

Package scope is really used so there are no naming conflicts for an application, especially when reusing classes from another framework. Packages are by default open, not sealed, which means a rogue class can be added to your package. If such a rogue class was added to a package, the scope of protected fields would not yield any security. By default, all fields and methods not declared public or private are protected, and can only be accessed within the same package; don’t rely on this for security.

Inner Classes

Simply put, when translated into bytecode, inner classes are "rebuilt" as external classes in the same package. This means any class in the package can access this inner class. The owner/enclosing/father classes’ private fields are morphed into protected fields as they are accessible by the now external inner class.

Hard Coding

Don't hard code any passwords, user IDs, etc in your code. Silly and bad design. Can be decompiled. Place them in a protected directory in the deployment tree.

Cloneability

Override the clone method to make classes unclonable unless required. Cloning allows an attacker to instantiate a class without running any of the class constructors. Define the following method in each of your classes:

public final Object clone() throws java.lang.CloneNotSupportedException {
  throw new java.lang.CloneNotSupportedException();
  }

If a clone is required, one can make one’s clone method immune to overriding by using the final keyword:

public final void clone() throws java.lang.CloneNotSupportedException {
 super.clone();
 }


Serialization/Deserialization

Serialization can be used to save objects when the JVM is "switched off". Serialization flattens the object and saves it as a stream of bytes. Serialization can allow an attacker to view the inner state of an object and even see the status of the private attributes.

To prevent serialization of one’s objects, the following code can be included in the object.

private final void writeObject(ObjectOutputStream out)
 throws java.io.IOException {
    throw new java.io.IOException("Object cannot be serialized");
 }

writeObject() is the method which kicks-off the serialization procedure. By overriding this method to throw an exception and making it final, the object cannot be serialized.

When Serialization of objects occurs, transient data gets dropped, so "tagging" sensitive information as transient protects against serialization attacks.

Deserialization can be used to construct an object from a stream of bytes, which may mimic a legitimate class. This could be used by an attacker to instantiate an object’s state. As with object serialization, deserialization can be prevented by overriding its corresponding method call readObject().


private final void readObject(ObjectInputStream in)
  throws java.io.IOException {
    throw new java.io.IOException("Class cannot be deserialized");
 }


«««« Main
(Table of Contents)
»»»»