Есть ли способ получить доступ к приватному методу во внутреннем классе с отражением или без - PullRequest
0 голосов
/ 23 октября 2019

Я пытаюсь сделать простой пример пользовательской и банковской программы, где вы должны гарантировать, что деньги не могут быть обмануты кем-то, кто может добавлять, наследовать, реализовывать существующие существующие классы, но не может редактировать исходные. Поэтому я спрашиваю, можете ли вы как-то установить баланс чьего-либо счета без предоставленной функции для перевода денег.

Я пытался использовать рефлексию, но вам нужно иметь публичные конструкторы, чтобы создать объект, для которого вы вызываете частные методы, нопоскольку все конфиденциально, я не могу назвать это.

public class Bank {
    private static Bank ourInstance = new Bank();
    public static Bank getInstance() {
        return ourInstance;
    }

    private Bank() {}

    public boolean requestTransfer(User user1, User user2, double amount) {
        BankAccount ba1 = (BankAccount) user1.getBankAccount();
        BankAccount ba2 = (BankAccount) user2.getBankAccount();
        if (!(hasAccount(ba1) && hasAccount(ba2)))
            return false;

        if (ba1.getBalance() >= amount)
        {
            ba1.setBalance(ba1.getBalance() - amount);
            ba2.setBalance(ba2.getBalance() + amount);
            return true;
        }
        return false;
    }

    private class BankAccount implements BankAccountInterface {
        private double balance;
        private User user;

        private BankAccount(double balance) {
            this.balance = balance;
        }

        @Override
        public double getBalance() {
            return balance;
        }

        @Override
        public User getUser() {
            return user;
        }

        public void setUser(User user) {
            this.user = user;
        }

        private void setBalance(double balance) {
            this.balance = balance;
        }
    }
}

public interface BankAccountInterface {
    double getBalance();
    User getUser();
}

public class User {
    private String username;
    private String password;
    private Date created_at;
    private BankAccountInterface bankAccount;
    //constructor getters and setters etc..
}

Если вы можете добавить свои собственные классы, наследовать текущие, использовать рефлексию или что-либо в вашем распоряжении, вы можете незаконно дать деньги пользователю.

Ответы [ 3 ]

6 голосов
/ 23 октября 2019

Это секретный вопрос. Вы можете использовать настройки диспетчера безопасности, предотвращающие отражение, см. this и this , манипулирование байтовым кодом не подлежит сомнению после загрузки класса, если вы не добавляете / удаляете /отредактируйте поля / метод / подписи классов, см. this . Существуют и другие уязвимости безопасности, вот официальный список 1008 *, с печально известной уязвимостью десериализации 1010 *, изначально созданной специально. Это известные проблемы без учета эксплойтов с нулевым днем ​​. Вот более подробное обсуждение 1014 * о тонкостях менеджера безопасности и некоторых API, связанных с этим эксплойтом .

2 голосов
/ 23 октября 2019

Вот код отражения для предоставления известному пользователю $ 1,000,000:

User user = /*assigned elsewhere*/;

// Get users bank account
Field bankAccountField = user.getClass().getDeclaredField("bankAccount");
bankAccountField.setAccessible(true); // Bypass 'private'
Object bankAccount = bankAccountField.get(user);

// Get bank account balance
Field balanceField = bankAccount.getClass().getDeclaredField("balance");
balanceField.setAccessible(true); // Bypass 'private'
double balance = (Double) balanceField.get(bankAccount);

// Add $1,000,000 to bank account
balance += 1_000_000;
balanceField.set(bankAccount, balance);
0 голосов
/ 23 октября 2019

Получив экземпляр внутреннего объекта, вы можете использовать рефлексию для вызова самого метода:

Method someMethod = innerObject.getClass().getDeclaredMethod("someMethod", Integer.class);
someMethod.setAccessible(true);
someMethod.invoke(innerObject, 5);

В этом примере, который вы предоставили, вы все равно можете использовать рефлексию для получения методов в классе пользователя.

Если вы можете добавить свои собственные классы, наследующие текущие, использовать отражение или что-нибудь в вашем распоряжении, можете ли вы незаконно дать пользователю деньги? Да, возможно, если методы реализованы без ограничений доступа для внешнего класса, это скорее вопрос безопасности. о коде Java.

...