Tuesday, 17 March 2020

Finalizer Attack in Java

Finalizer attack is a technique of accessing the information (can be methods, fields) of a class through finalizer method.

Let me explain with an example.

AccountOperations.java
package com.sample.app;

public class AccountOperations {

	public AccountOperations() {
		if (!isAuthorized()) {
			throw new SecurityException("You can't access the account");
		}
	}

	public boolean isAuthorized() {
		return false;
	}

	public void transferMoney(double amount) {
		System.out.println("Transferring " + amount + " to beneficiary");
	}

}

As you see AccountOperations.java class, when you try to create an object of AccountOperations class, it checks whether user is authorized or not. If user is not authorized constructor throws SecurityException.

How can I transfer money even I got SecurityException?
Let’s extend the class FakeAccountOperations and override finalize method. ‘finalize’ method is called by java run time just before the object gets garbage collected. So I can override the finalize method and call super class methods.

FakeAccountOperations.java
package com.sample.app;

public class FakeAccountOperations extends AccountOperations {

	public FakeAccountOperations() {
		
	}
	
	@Override
	protected void finalize() {
		System.out.println("Still I can transfer money");
		this.transferMoney(100);
		System.exit(0);
	}
}

As you see above snippet, I called ‘transferMoney’ method from finalize() method.

App.java
package com.sample.app;

import java.util.concurrent.TimeUnit;

public class App {

	public static void main(String args[]) throws InterruptedException {
		AccountOperations accOperations = null;

		try {
			accOperations = new FakeAccountOperations();
		} catch (Exception e) {
			System.out.println(e.getMessage());
		}

		System.gc();
		TimeUnit.MINUTES.sleep(10);
	}

} 

Output
You can't access the account
Still I can transfer money
Transferring 100.0 to beneficiary

How can I defend finalizer attack?
Solution 1: Declare the class using ‘final’ modifier, so it can’t be extended.

AccountOperations.java
package com.sample.app;

public final class AccountOperations {

	public AccountOperations() {
		if (!isAuthorized()) {
			throw new SecurityException("You can't access the account");
		}
	}

	public boolean isAuthorized() {
		return false;
	}

	public void transferMoney(double amount) {
		System.out.println("Transferring " + amount + " to beneficiary");
	}

}

Solution 2: Define ‘finalize’ method using final modifier, so it can’t be override by sub class.
package com.sample.app;

public class AccountOperations {

	public AccountOperations() {
		if (!isAuthorized()) {
			throw new SecurityException("You can't access the account");
		}
	}

	public boolean isAuthorized() {
		return false;
	}

	public void transferMoney(double amount) {
		System.out.println("Transferring " + amount + " to beneficiary");
	}

	final protected void finalize() {
		
	}
} 

Solution 3: Using a Boolean flag.
Set a Boolean flag to true, when user is authorized and use this flag before performing any operation.

AccountOperations.java

package com.sample.app;

public class package com.sample.app;

public class AccountOperations {
	private boolean isUserAuthorized = false;

	public AccountOperations() {
		if (!isAuthorized()) {
			throw new SecurityException("You can't access the account");
		}
		isUserAuthorized = true;
	}

	public boolean isAuthorized() {
		return false;
	}

	public void transferMoney(double amount) {
		if (!isUserAuthorized) {
			System.out.println("You are not authorized");
			return;
		}
		System.out.println("Transferring " + amount + " to beneficiary");
	}

}
 {
	private boolean isUserAuthorized = false;

	public AccountOperations() {
		if (!isAuthorized()) {
			throw new SecurityException("You can't access the account");
		}
		isUserAuthorized = true;
	}

	public boolean isAuthorized() {
		return false;
	}

	public void transferMoney(double amount) {
		if (!isUserAuthorized) {
			System.out.println("You are not authorized");
			return;
		}
		System.out.println("Transferring " + amount + " to beneficiary");
	}

}


You may like

No comments:

Post a Comment