簡體   English   中英

有沒有辦法在有或沒有反射的情況下訪問內部類中的私有方法

[英]Is there a way to access private method in inner-class with or without reflection

我正在嘗試做一個用戶和銀行程序的簡單示例,您必須保證金錢不會被可以添加、繼承、實現當前現有類但不能編輯初始類的人欺騙。 所以我問你是否可以在沒有提供 function 用於匯款的情況下以某種方式設置某人的帳戶余額。

我試過使用反射,但你必須有公共構造函數來制作一個 object ,你可以在上面調用私有方法,但由於一切都是私有的,我不能調用它。

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..
}

如果您可以添加自己的類繼承當前的類,使用反射或任何您可以使用的東西,您可以非法給用戶錢。

這是一個安全問題。 您可以使用安全管理器設置來防止反射,請參閱,在 class 加載后,通過字節碼操作更改接口是不可能的,請參閱 不過還有其他安全漏洞,這里是官方列表,臭名昭著的反序列化漏洞最初是故意設計的。 這些都是已知問題,沒有考慮零日漏洞。 這是關於安全管理器的復雜性和與此漏洞相關的某些 API 的更詳細討論

這是給已知用戶 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);

一旦有了內部 object 的實例,就可以使用反射來調用方法本身:

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

在您提供的這個示例中,您仍然可以使用反射來獲取用戶 Class 中的方法。

如果您可以添加自己的類繼承當前的類,使用反射或任何您可以使用的東西,您可以非法給用戶錢嗎?如果方法是在沒有外部 class 的訪問限制的情況下實現的,是可能的,這與安全性有關,而不是與 java 代碼有關。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM