Wiki Markup |
---|
A nonfinal class or method that is not meant to be inherited can be overridden by an attacker if it is not declared as {{final}} \[3\]. |
Wiki Markup |
---|
If inheritance is to be limited to trusted implementations for a public, nonfinal class, then the class type should be confirmed before creating the instance at each place where an instance of the nonfinal class can be created. A SecurityManager check should be enforced on detecting a subclass (Chapter 6 of \[2\]). |
...
In this example, an attacker can easily create an instance and override methods of class BankOperation
. This example also assumes the absence of appropriate Security Manager checks.
Code Block |
---|
|
class BankOperation {
//theThe account balance has already been retrieved from the database and stored in the foll variable
private Integer balance = 5000;
public BankOperation() {
//invoke java.lang.Object.getClass to get class instance
Class clazz = getClass();
//shows the class of the instantiated object
System.out.println(clazz);
}
public void getBalance() {
System.out.println("The current balance is: $" + balance);
}
}
//thisThis class has been written by the attacker
public class SubClass extends BankOperation {
public void getBalance() {
//The attacker can change his account balance to any value he wants.
Integer modifiedBalance = 0;
//to read the new balance from the attacker
InputStreamReader input = new InputStreamReader(System.in);
Field balance=null;
BufferedReader reader = new BufferedReader(input);
System.out.print("Enter balance: ");
try {
modifiedBalance = Integer.parseInt(reader.readLine());
//this gets the private field from the superclass
balance = this.getClass().getSuperclass().getDeclaredField("balance");
//this changes the accessibility so that field can now be accessed
if (!Modifier.isPublic(balance.getModifiers())){
balance.setAccessible(true);
}
//retrieve the original balance
System.out.println("Original Balance: $"+balance.get(this));
//change the balance
balance.set(this, modifiedBalance);
//display the new changed balance
System.out.println("New Balance: $"+balance.get(this));
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
SubClass subclass = new SubClass();
subclass.getBalance();
}
}
|
Compliant Solution
This compliant solution can be achieved limits the extensibility of the sensitive class by using the keyword final
, thus ensuring that the sensitive class cannot be extended final
keyword.
Code Block |
---|
|
final class BankOperation{
//normal coding...
}
|
In case the class needs to be extended, then permissions should be checked in case a subclass is detected during construction so that malicious implementations are blocked.
...