Использование менеджера безопасности с отражением при доступе к файлу jar - PullRequest
0 голосов
/ 16 сентября 2018

После реализации моей платформы, позволяющей динамически загружать файлы JAR с помощью отражения, я столкнулся с проблемой безопасности.Файл jar может быть «опасным» и содержать код, который может на что-то повлиять, поэтому на SO я сталкиваюсь с использованием SecurityManager.

. Я загружаю файл jar следующим образом (пример с жестким кодомфайл):

URLClassLoader clsLoader = URLClassLoader
    .newInstance(new URL[] { new URL("file:/C://Temp/SettingsApp.jar") });
Class<?> cls = clsLoader.loadClass("iezon.app.SettingsApp");
JPanel settingsApp = (JPanel) cls.newInstance();

Я пытался использовать SecurityManager примерно так:

try {
    SecurityManager sm = new SecurityManager();
    Object context = sm.getSecurityContext();
    sm.checkPermission(new AllPermission(), context);
    settingsAppPanel = (JPanel) cls.newInstance();
} catch (AccessControlException e) {
    e.printStackTrace();
}

Тест с AllPermission() работает и дает мне следующее исключение:

java.security.AccessControlException: доступ запрещен ("java.security.AllPermission" "" "")

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

Я наткнулся на BasicPermission, однакоЭто абстрактный класс, и его нельзя создавать как AllPermission, и, соответственно, я не могу найти какую-либо информацию о приближении к нему.Любая помощь будет оценена!

1 Ответ

0 голосов
/ 19 сентября 2018

Как отмечалось в комментариях @ Holger , единственный способ реализовать использование диспетчера безопасности - это динамически создавать политики. Поэтому, когда разработчик загружает новое приложение в магазин приложений, ему предоставляется набор политик для объявления того, что его приложение использует. В приложении это передается пользователю, который просит его подтвердить эту политику (на свой страх и риск, если он включает сокеты и т. Д.), А затем создается политика, и приложение может работать:

if (!app.policyIsAgreedTo()) {
        if(readPolicy(app).get(0).equalsIgnoreCase("grant {")) {
            app.setPolicy(true);
        } else {
            throw new Exception("App policy has not been agreed to.");
        }
    }

    if (app.policyIsAgreedTo()) {
        System.setProperty("java.security.policy", "file:/C:/Temp/" + app.getName() + ".policy");
        System.setSecurityManager(new SecurityManager());
        JPanel panel = (JPanel) app.getObject().newInstance();
        System.setSecurityManager(null);
        return panel;
    }

    throw new Exception("App policy has not been agreed to.");

Политика создается следующим образом:

public static void createPolicy(ArrayList<String> policies, App app) {

    try {
        FileWriter fileWriter =
                new FileWriter("C:/Temp/" + app.getName() + ".policy");
        BufferedWriter bufferedWriter =
                new BufferedWriter(fileWriter);

        bufferedWriter.write("grant {");
        bufferedWriter.newLine();

        for(String policy : policies) {
            bufferedWriter.write("    permission java.lang.RuntimePermission \"" + policy + "\";");
            bufferedWriter.newLine();
        }

        bufferedWriter.write("};");
        bufferedWriter.close();

    } catch(IOException ex) {
        ex.printStackTrace();
    }
}

Приложение выполняет API-вызов к магазину приложений, собирая разрешения, необходимые приложению, затем вызывается простой createPolicy() с разрешениями в ArrayList, т. Е.

new ArrayList<String>() {{ add("setSecurityManager"); }}; // Etc...
...