Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Может ли синглетон быть дырой в безопасности (Java) ?

276
30 января 2008 года
Rebbit
1.1K / / 01.08.2005
Ги. А я тут какраз недавно читал про рефлексию в Java. Видимо человек я не оч хороший потому что мне в голову сразу лезут мысли как етим можно воспользоваться чтобы комуто навредить :). Ну собственно ето только лирический отступ.

Шо же получается по факту. Подключив свой класс к уже роботающей системе используя рефлексию можно наделать много плохих вещей особенно в том случае если можно получить инстанс какихто важних сучностей (которые кста часто в синглетоны пихают). А синглетон дает нам етот инстанс. Так что я меняю свое мнение. Слишком много минусов получается для етого паттерна. Жаль переголосовать нельзя.

ЗЫ. на выходных хочу поекспериментировать с ломанием синглетонов рефлексией. Может что интересного получится.
63
30 января 2008 года
Zorkus
2.6K / / 04.11.2006
С рефлексией дело обстоит так.
Все средства для того, чтобы "ломать синглотоны" в ней, конечно, есть. Проблема только в том, в каких ситуациях это будет разрешено исполняющей системой.
Итак, пусть есть простой класс-синглтон.
Код:
package reflectiontest;

public class SimpleSingleton{

    private static SimpleSingleton self = new SimpleSingleton();
   
    private SimpleSingleton(){              
    }

    public static SimpleSingleton getInstance(){
        return self;
    }

}

И есть код в другом классе, работающий с этими синглтонами.
Задача: - создать в этом коде два объекта класса-синглтона.
Простейший случай:
Код:
package reflectiontest;

import java.lang.reflect.*;

public class SingletonTest {
   
    public static void main(String[] args) {
        try {

            // Первый объект создается самым типичным способом;
            SimpleSingleton firstCopyOfSingleton = SimpleSingleton.getInstance();

            //----------------------------------------------------------------------
                   
            // Второй объект создается через рефлексию.
            Class SingletonClass = SimpleSingleton.class;
           
            //Получаем закрытый конструктор без параметров
            Constructor<SimpleSingleton> constr = SingletonClass.getDeclaredConstructor();
           
            /* Ключевой момент - отключается проверка доступа к конструктору
             * (Иначе вызвать его не получиться, т.е. он private).
             * В этом месте программа выдаст SecurityException, если менеджер безопасности
             * для приложения установлен, и данное действие запрещено.            *
             */
            constr.setAccessible(true);
           
            SimpleSingleton secondCopyOfSingleton = constr.newInstance();
           
            System.out.println(firstCopyOfSingleton == secondCopyOfSingleton);
           
        } catch (InstantiationException ex) {
            ex.printStackTrace();
        } catch (IllegalAccessException ex) {
            ex.printStackTrace();
        } catch (IllegalArgumentException ex) {
            ex.printStackTrace();
        } catch (InvocationTargetException ex) {
            ex.printStackTrace();
        } catch (NoSuchMethodException ex) {
            ex.printStackTrace();
        } catch (SecurityException ex) {
            ex.printStackTrace();
        }      
    }
}

Нетрудно убедиться, что программа выдаст на консоль - false.
Т.е. у нас получилось создать ДВА объекта-синглтона - получилось потому, что менеджер безопасности по умолчанию не установлен.
63
30 января 2008 года
Zorkus
2.6K / / 04.11.2006
Теперь - как добиться, чтобы диспетчер защиты не пропускал такие махинации.
Прежде всего его нужно установить. Можно сделать это из программы, вызвав в main(...) -
 
Код:
System.setSecurityManager(new SecurityManager());
.
Можно потребовать исполнение приложение с его использованием от JVM - запуская приложение с ключем -Djava.security.manager.

Дальше - нужно, чтобы операции с рефлексией (только потенциально опасные, конечно) запрещались диспетчером защиты. Для этого в файле jre_home/lib/security/java.policy в блок привилегий добавим -
 
Код:
// default permissions granted to all domains

grant {
...
permission java.lang.reflect.ReflectPermission "suppressAccessChecks";
...
}

Cнова запускаем код, приведенный выше - получаем следующее
 
Код:
[olorin@varjag ~]$ java -Djava.security.manager -jar "/home/olorin/NetBeansProjects/TestDudgeJava/dist/TestDudgeJava.jar"
java.security.AccessControlException: access denied (java.lang.reflect.ReflectPermission suppressAccessChecks)
        at java.security.AccessControlContext.checkPermission(AccessControlContext.java:342)
        at java.security.AccessController.checkPermission(AccessController.java:556)
        at java.lang.SecurityManager.checkPermission(SecurityManager.java:550)
        [color=red]at java.lang.reflect.AccessibleObject.setAccessible(AccessibleObject.java:125)
        at reflectiontest.SingletonTest.main(SingletonTest.java:25) [/color]
[olorin@varjag ~]$


Это, конечно, очень краткое и неполное описание того, как разрешается/запрещается колдовство над классами. Любым поправкам буду рад, т.к. с этом аспектом Java на практике почти не сталкивался. Попозже, может, найду еще какие-нибудь тонкости.
276
30 января 2008 года
Rebbit
1.1K / / 01.08.2005
Вот-вот. Только меня больше смущает тот факт что даже если

Цитата: Zorkus

 
Код:
/* Ключевой момент - отключается проверка доступа к конструктору
              * (Иначе вызвать его не получиться, т.е. он private).
              * В этом месте программа выдаст SecurityException, если менеджер безопасности
              * для приложения установлен, и данное действие запрещено.             *
              */
             constr.setAccessible(true);


не проканает изза етого менеджера безопасности (про него я еще не узнавал) то всеровно мы легко и просто получаем инстанс сущности и каверкаем ее через публичные set методы (если они конечно есть).
Что получается. Чтоб такого не случилось надо глобальный обект сделать локальной переменной функции main.

ЗЫ. После прочтения второго поста по поводу менеджера безопасности и запрета рефлексии.

А может она мне самому пригодится ? Можно отключить ее для чужого класса а себе оставить ?

63
30 января 2008 года
Zorkus
2.6K / / 04.11.2006
Цитата: Rebbit
то всеровно мы легко и просто получаем инстанс сущности и каверкаем ее через публичные set методы (если они конечно есть).


Эээ, не понял? Если переменная

 
Код:
private static SimpleSingleton self = new SimpleSingleton();

имеет открытые сетеры, мы конечно можем ее повредить - но это же не нормальная реализация синглтона. Можно обратиться не к конструктору, а к этому полю напрямую - ну так для этого все равно проверяются ReflectPermission.
Цитата:

А может она мне самому пригодится ? Можно отключить ее для чужого класса а себе оставить ?


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

 
Код:
checkPermission(new ReflectPermission("suppressAccessChecks")))

может либо запретить, либо разрешить такое вообще. Для разграничния на уровне классов видимо, придется реализовывать свой диспетчер защиты, если такое вообще можно сделать. Как время будет (сессия ;)), проверю.
P.S. А как ты собрался это использовать? Тут же речь идет о работе в рамках одного приложения, ты что, работаешь с какими-то библиотеками (предоставляешь библиотеку), активно использующими рефлексию для потенциально запрещенных вещей? Поделись ;)
Вероятно, кстати, что такое используется в IDE. Но в их исходниках меня копаться пока не тянет ;)
276
30 января 2008 года
Rebbit
1.1K / / 01.08.2005
Цитата: Zorkus
Эээ, не понял? Если переменная
 
Код:
private static SimpleSingleton self = new SimpleSingleton();
имеет открытые сетеры, мы конечно можем ее повредить - но это же не нормальная реализация синглтона



Я не о том. Я не о создании нового обекта а о роботе с етим единственным синглетоном.
Припустим у синглетона есть приватное поле "важная_опция" и публичные методы get/set"важная_опция". Припустим злоумышленник не может создать нового инстанса, но он может получить существующий вызвав getInstance, после чего вызывать set"важная_опция". Без инстанса не получится вызвать нестатический метод set"важная_опция".
Если сделать не синглетоном, ему придется доставать инстанс из поля какогото другого обекта-держателя. Для етого нужен и инстанс держателя. И так далее вверх по структуре классов со звязями "содержит в себе". Посему я и говорю что самый верхний обект который содержит в себе другие логично делать не полем, а локальной переменной функции main. Вот такой у меня бред в голове.

Цитата: Zorkus
Хорстманн пишет, что для привилегии ReflectPermission не задается, сущность, для которой проверяется привилегия - т.е. как я пока понял, менеджер защиты, работающий по файлам политики, через
 
Код:
checkPermission(new ReflectPermission("suppressAccessChecks")))
может либо запретить, либо разрешить такое вообще. Для разграничния на уровне классов видимо, придется реализовывать свой диспетчер защиты, если такое вообще можно сделать. Как время будет (сессия ;)), проверю.


Будем читать.

63
30 января 2008 года
Zorkus
2.6K / / 04.11.2006
Цитата: Rebbit
Я не о том. Я не о создании нового обекта а о роботе с етим единственным синглетоном.
Припустим у синглетона есть приватное поле "важная_опция" и публичные методы get/set"важная_опция". Припустим злоумышленник не может создать нового инстанса, но он может получить существующий вызвав getInstance, после чего вызывать set"важная_опция".
Без инстанса не получится вызвать нестатический метод set"важная_опция".
Если сделать не синглетоном, ему придется доставать инстанс из поля какогото другого обекта-держателя. Для етого нужен и инстанс держателя. И так далее вверх по структуре классов со звязями "содержит в себе". Посему я и говорю что самый верхний обект который содержит в себе другие логично делать не полем, а локальной переменной функции main. Вот такой у меня бред в голове.


Погоди. Что за гипотетический злоумышленник-то? Откуда начинается его "атака" и какова ее цель? Опиши уж тогда.
И еще - это ты сейчас про работу именно в Java говоришь, или в общем?
В общем случае, кстати, приложение совершенно необязательно имеет какой-то главный класс и точку входа в него - main.

276
30 января 2008 года
Rebbit
1.1K / / 01.08.2005
Цитата: Zorkus
И еще - это ты сейчас про работу именно в Java говоришь, или в общем?
В общем случае, кстати, приложение совершенно необязательно имеет какой-то главный класс и точку входа в него - main.


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

Цитата: Zorkus
Погоди. Что за гипотетический злоумышленник-то? Откуда начинается его "атака" и какова ее цель? Опиши уж тогда.


Виноват. Действительно думаю о своей задаче. Она для меня суто тренировочная. Хочу попрактиковаться перед тем как идти роботать с етим языком. Суть дела такова.
Шахматная доска. На ней можно играть разные игры. Есть класс ИГРА, класс (или интерфейс) ИГРОК. Я делаю класс ИГРА. Ктото реализирует интерфейс ИГРОК. Реализация подключается к примеру с помощю учазания пути к jar-файлу. Про биндинг я еще не читал (медленно учусь по своим причинам). Я вызываю его функцию "сделать_ход". Я не хочу анализировать его код на безопасность, но не хочу чтоб он мог сделать чтото плохое. В даном случае смохлевать в игре. Ну вот такой собственно случай. Реализации пока никакой. Только идея.

63
30 января 2008 года
Zorkus
2.6K / / 04.11.2006
Цитата: Rebbit
Да говорю именно о ней. Возможно етот розговор лутше в твой роздел перетащить, хотя ето всетаки про синглетон.

Какой это еще "мой" раздел? :)
Ну продолжу высказываться, если зарвемся и слишком далеко от синглтонов отойдем - пусть Green перенесет в Java.

Цитата: Rebbit

Виноват. Действительно думаю о своей задаче. Она для меня суто тренировочная. Хочу попрактиковаться перед тем как идти роботать с етим языком. Суть дела такова.
Шахматная доска. На ней можно играть разные игры. Есть класс ИГРА, класс (или интерфейс) ИГРОК. Я делаю класс ИГРА. Ктото реализирует интерфейс ИГРОК. Реализация подключается к примеру с помощю учазания пути к jar-файлу. Про биндинг я еще не читал (медленно учусь по своим причинам). Я вызываю его функцию "сделать_ход". Я не хочу анализировать его код на безопасность, но не хочу чтоб он мог сделать чтото плохое. В даном случае смохлевать в игре. Ну вот такой собственно случай. Реализации пока никакой. Только идея.


Что ты подразумеваешь под "жульничеством"? Запуск кода стирания файла, например - это сюда входит?
Еще - какая у тебя связь ИГРЫ и ИГРОКА на уровне классов?
P.S. Что-то да, от синглтонов мы отдалились...

3.7K
31 января 2008 года
bioflash
169 / / 01.10.2005
Мое мнение немножко отличается от вашего. Синглтон здесь ни при чем - лучше прочитайте что написала SUN в туториале про Reflection - раздел "Drawbacks of Reflection". Вот маленькая цитата:

Security Restrictions
Reflection requires a runtime permission which may not be present when running under a security manager. This is in an important consideration for code which has to run in a restricted security context, such as in an Applet.
Exposure of Internals
Since reflection allows code to perform operations that would be illegal in non-reflective code, such as accessing private fields and methods, the use of reflection can result in unexpected side-effects, which may render code dysfunctional and may destroy portability. Reflective code breaks abstractions and therefore may change behavior with upgrades of the platform.

То есть если ты имеешь синглтон или имеешь просто какой-то объект - ето не важно. Если ты изменишь какое-то его скрытое поле, то за ето будешь отвечать только ты. Таким образом я считаю что ни синглтон ни рефлекшен ето не дыры в безопасности - ето средства. Пользоваться ими или нет - ето уже ваша прерогатива :)
276
31 января 2008 года
Rebbit
1.1K / / 01.08.2005
Цитата: Zorkus
Что ты подразумеваешь под "жульничеством"? Запуск кода стирания файла, например - это сюда входит?


Неа. Хотя ето тоже былобы не плохо,, но я не знаю как такео запретить.

Цитата: Zorkus
Еще - какая у тебя связь ИГРЫ и ИГРОКА на уровне классов?


В даном случае да. Хотя я говорил. Задача тренировочная. Хочу сделать на уровне класов, потом через HTTP, ВебСервис. Может еще чтото попробую. Я не говорю что ето правильные решения но учится то на чемто надо.

Теперь про конкретный случай. Интерфейс ИГРОК. В нем метод который совершает ход. Ему передается состояние на игровом поле. Он возвращает ход. Сам обект игрока жывой на протяжении всей игры. Вызов хода игрока из метода класса ИГРА. Естественно реализацыю ИГРОКА делают неизвесные мне люди. Ето не новая идея и такие програмы уже есть. Загружается класс реализацыи игрока ... ну пускай пока рефлексией (я пока ни до чего умнее не дочитался но решения полутше наверно есть)
Что я думаю. Я не профи и сжульничать наверно ктото сможет. Ну всмысле какаято реализация игрока может обмануть мой класс ИГРА. Поетому играем игру с двумя игроками 2 раза. Один раз запрашиваем ходы у игроков и пишем их в лог. Ну например в БД. Потом проганяем игру еще раз по логу но уже без игроков и повторно проверяем соблюдение всех правил.
Ето хорошо, но хочется также какможно больше обезопасится от игроков, при етом как можно меньше им запрещая. Ну ето чисто для спортивного интереса.

276
31 января 2008 года
Rebbit
1.1K / / 01.08.2005
 
Код:
public class Starter {
   
    public static void main(String[] args){
        SystemRunable mainRunable = new SystemRunable();
        mainRunable.run();
    }
   
}

Код:
/* Некий образ нашей системы (ето я уже забегаю вперед,
 * делаю так как бы хотел чтоб было но пока с синглетонами).
 * Фактически должен поддерживаться интерфейс IRunabe
 * но для упрощения упустим */
public class SystemRunable {

    /* Еще бы пригодились init/destroy но их тоже упустим
     * */
    public int run(Object... params){
        System.out.println(Singleton.getInstance().getData());
        try {
            Class cl = Class.forName("Crack");
            Object crack = cl.newInstance();
            if (ICrack.class.isInstance(crack)){
                ((ICrack)crack).crack();
            }
            else {
                System.out.println("ICrack not supported.");
                return 2;
            }
        } catch (Exception e){
            System.out.println(e.getMessage());
            return 1;
        }
        System.out.println(Singleton.getInstance().getData());
        return 0;
    }
   
}

Код:
/* Вот его ломать будем
 * */
public class Singleton {
   
    private static Singleton instance = new Singleton();
   
    public static Singleton getInstance(){
        return instance;
    }
   
    /* Надо искаверкать ету строчку
     * */
    private String data;
   
    private Singleton(){
        this.data = "Data is GOOD :)";
    }
   
    public String getData(){
        return this.data;
    }
   
    /* В большинстве случаев не удастса избежать методов
     * меняющих состояние екземпляра
     * */
    public void setData(String data){
        this.data = data;
    }

}

 
Код:
/* Вот етим ломать будем
 * */
public interface ICrack {

    void crack();
   
}

Код:
import java.lang.reflect.Method;

/* Реализация ламалки
 * */
public class Crack implements ICrack{
   
    public void crack(){
        try {
            Class cl = Class.forName("Singleton");
            Method mGetInstance = cl.getDeclaredMethod("getInstance");
            /* Вот то о чем я говорил.
             * Можна достать инстанс синглетона и испортить его
             * */
            Object singleton = mGetInstance.invoke(null);
            Method mSetData = cl.getDeclaredMethod("setData", String.class);
            mSetData.invoke(singleton, "Data is BAD :(");
            System.out.println(">:-[");
        } catch (Exception e){
            System.out.println(e.getMessage());
            return;
        }
    }

}


Чтото типа такого. Второй екземпляр не делается но существующий калечится. И ни одного обращения к прайвету. Будете говорить "Ну дик метод set есть". А куда я без него. Что мне самому себе руки связывать :)
276
31 января 2008 года
Rebbit
1.1K / / 01.08.2005
Как учил Green - глобальная точка входа.
Привожу только изменения.
Код:
/* Некий образ нашей системы
 * Фактически должен поддерживаться интерфейс IRunabe
 * но для упрощения упустим */
public class SystemRunable {

    private Context context = new Context();
   
    /* Еще бы пригодились init/destroy но их тоже упустим
     * */
    public int run(Object... params){
        PsevdoSingleton pSingleton = context.getPsevdoSingleton();
        System.out.println(pSingleton.getData());
        try {
            Class cl = Class.forName("Crack");
            Object crack = cl.newInstance();
            if (ICrack.class.isInstance(crack)){
                ((ICrack)crack).crack();
            }
            else {
                System.out.println("ICrack not supported.");
                return 2;
            }
        } catch (Exception e){
            System.out.println(e.getMessage());
            return 1;
        }
        System.out.println(pSingleton.getData());
        return 0;
    }
   
}
Код:
/* Ну уж не знаю правильно ли назвал.
 * Можно ли ето щитать фабрикой при final ?
 * Можно ли ето щитать контекстом ?
 * */
public class Context {
   
    private final PsevdoSingleton pSingleton = new PsevdoSingleton();
   
    public final PsevdoSingleton getPsevdoSingleton(){
        return pSingleton;
    }

}
Код:
/* Вот его ломать будем
 * */
public class PsevdoSingleton {
   
    /* Надо искаверкать ету строчку
     * */
    private String data;
   
    public PsevdoSingleton(){
        this.data = "Data is GOOD :)";
    }
   
    public String getData(){
        return this.data;
    }
   
    /* В большинстве случаев не удастса избежать методов
     * меняющих состояние екземпляра
     * */
    public void setData(String data){
        this.data = data;
    }

}
Как теперь реализовать Crack я не знаю. Вот знакомый обещал все что угодно рефлексией поламать. Ну вперед. :)

Если при таком подходе можно изменить поле синглетона то дыра наверно не в синглетоне а в рефлексии.
3.7K
31 января 2008 года
bioflash
169 / / 01.10.2005
Перед тем как приступать к ломанью твоего синглтона нужно выяснить одну маленькую деталь. Зачем в етом примере синглтон? Какое его назначение?

Мне кажется что твой пример синглтона не очень-то логичный. Представь ситуацию когда у тебя запущено несколько потоков? И им нужно всем использовать один бин сущности (синглтон). Как ты будешь им его надавать? Мне кажется что при таком раскладе тебе придётся предоставлять каждому потоку один и тот же контекст (доступ к твоему синглтону ты даешь только через контекст).
Вот мне интересно как ты будешь надавать всем потокам один контекст?!
Если же ты будешь делать разные контексты, то твой синглтон в контексте уже не будет синглтоном ;)
276
31 января 2008 года
Rebbit
1.1K / / 01.08.2005
Цитата: bioflash
Мне кажется что при таком раскладе тебе придётся предоставлять каждому потоку один и тот же контекст (доступ к твоему синглтону ты даешь только через контекст).
Вот мне интересно как ты будешь надавать всем потокам один контекст?!
Если же ты будешь делать разные контексты, то твой синглтон в контексте уже не будет синглтоном ;)


Ето проблемы контекста.

Код:
public class Context {
   
    // Убрал final у поля.    
    private PsevdoSingleton pSingleton = new PsevdoSingleton();
   
    public final PsevdoSingleton getPsevdoSingleton(){
        return pSingleton;
    }

    public final void setPsevdoSingleton(........){
          .........
    }
}
Так устроит ?
Лутше конструктор сделать, передавать ему другой контекст и без setPsevdoSingleton обойтись. Но поскольку ты хотел доступ к прайветам то ето меня не спасет. Я тебя ограничевать не стану :)

ЗЫ. Ступил. Ето проблема не только Context, а еще и той сущности которая над SystemRunable стоять будет. Но ета проблема решается.
3.7K
31 января 2008 года
bioflash
169 / / 01.10.2005
Я не об етом тебя спрашивал. Меня интересует как ти будешь предоставлять свой контекст другим потокам. Или будешь создавать новий? Если будешь создавать новий, то тогда синглтон в контексте - ето не синглтон :) так как ти сам созидаешь много копий "синглтона" :)
276
31 января 2008 года
Rebbit
1.1K / / 01.08.2005
Я что сказал что ето синглетон. НЕТ. Ето простой обект. Если мне нужно чтоб он был один я контролирую ето сам. Передавать буду параметрами методов. Или ты меня просиш чтоб я сделал свой класс-поток и чтото в его поле сунул.
Как ето сделать я подумаю дома.
63
31 января 2008 года
Zorkus
2.6K / / 04.11.2006
Сначала в общем:
Цитата: Rebbit
Неа. Хотя ето тоже былобы не плохо,, но я не знаю как такео запретить.


С точки зрения гарантии общей безопасности, можно заставить авторов реализаций подписывать jar-ники (если реализации игровой логики поставляются в них). Вот это может быть очень эффективно.

Цитата: Rebbit

В даном случае да. Хотя я говорил. Задача тренировочная. Хочу сделать на уровне класов, потом через HTTP, ВебСервис. Может еще чтото попробую. Я не говорю что ето правильные решения но учится то на чемто надо.


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

Цитата: Rebbit

Что я думаю. Я не профи и сжульничать наверно ктото сможет. Ну всмысле какаято реализация игрока может обмануть мой класс ИГРА. Поетому играем игру с двумя игроками 2 раза. Один раз запрашиваем ходы у игроков и пишем их в лог. Ну например в БД. Потом проганяем игру еще раз по логу но уже без игроков и повторно проверяем соблюдение всех правил.

Если ход запрещен, но я с помощью рефлексии его делаю - он может и не записаться в лог (если, например, ты логируешь из метода, меняющего что-то в параметрах игры - то я могу это поменять напрямую, не вызвав метод, точно так же я могу обойти любых слушателей таких изменений и т.п.). И начиная с некоторого момента лог будет просто битый - т.е. ход следующего игрока может быть признан некорректным - по "официальным" данным, хотя по создавшейся "скрытым образом во время игры" ситуации - он допустим. Т.е. ты можешь сделать вывод, что игра, начиная с некоторого момента, "сдохла". Как предполагаешь отлавливашь такие ситуации?
biolash - Ты совершенно прав в своем первом посте - что сам по себе синглтон не является дырой в защите - т.е. является ей не больше, чем любой другой паттерн, полагающийся на сокрытие данных в ситуации, когда инкапсуляция нарушается "хирургическим методом".

А потому мы, видимо, разбиваем рассуждение на две ветки:

1. Особенности безопасности данных (в том числе разные проявления и последствия нарушения инкапсуляции) при рефлексии, и способы запрета таких нарушений. Можно попробовать взломать фабрику или какие другие паттерны, которые предложит Rebbit или еще кто-нибудь :).
2. Особенности работы синглтонов в многопоточных средах и обсуждения решения Rebbit'a в его проекте.
Какие будут мнения?
Тогда можно уже и разобрать и покомментировать код выше.

276
31 января 2008 года
Rebbit
1.1K / / 01.08.2005
Цитата: Zorkus
biolash - Ты совершенно прав в своем первом посте - что сам по себе синглтон не является дырой в защите - т.е. является ей не больше, чем любой другой паттерн, полагающийся на сокрытие данных в ситуации, когда инкапсуляция нарушается "хирургическим методом".


Ну и где ето я инкапсуляцию нарушил ? Я ж прайветов не трогал вовсе.
Или под "хирургическим методом" ты имееш ввиду просто рефлексию.

Про направление розговора: решения в моем проекте ето дело тридцатое. Проекта то нет да и если будет то мелочный. Я просто думаю, могу ли я сделать програму в которую пущу еще чей то код и не буду бояться что она изменит состояние моих обектов несанкционировано. Доступ к внешним ресурсам (файли, БД, железо меня в данный момент не интересуют. Только мои обекты). И смогу ли я с такой системой удобно роботать.
При етом я не хочу запрещать рефлексию как такую, но доступ к прайветам конечно запрещу. Если есть такая техническая возможность.

63
31 января 2008 года
Zorkus
2.6K / / 04.11.2006
Откровенно говоря, сходу не скажу. Могу только сказать вот что.
Обыкновенно, менеджер безопасности служит для того, чтобы программа из непроверенного источника не могла повредить машине пользователя. Соответственно, под это заточена модель безопасности. В твоей ситуации, получается, что ты хочешь обезопасить одну часть своей программы от другой. Соответственно, ты никак не можешь повлиять на политику исполнения Java-приложений, поскольку не имеешь прав на той машине (пользователя), где они будут исполняться. Думаю, кастомный менеджер безопасности единственно тебе поможет - и еще, уместны будут проверки всевозможные этих самых источников кода (подписание jar-ников, X509 сертификаты, еще что-то, быть может). Подробней трудно сказать мне.
276
31 января 2008 года
Rebbit
1.1K / / 01.08.2005
Цитата: Zorkus
Соответственно, ты никак не можешь повлиять на политику исполнения Java-приложений, поскольку не имеешь прав на той машине (пользователя), где они будут исполняться.


Ну такое на мишине клиента я делать не собираюсь. Только на моей машине. На моем сервере.
Собственно я только что для себя сформулировал что меня интересует.
Смогу ли я сделать то что сказал в теме про синглетоныGreen ? Смогу ли я сделать так чтоб небыло глобальных данных вовсе? Только точка входа. Смогу ли я так роботать ? Защитит ли ето мои обекты от рефлексии ?
Во втором моем примере я не могу повредить своих обектов потомучто не могу до них добраться. Не знаю как получить инстанс. Могу создать новые, но зачем. Наверно могу визвать main повторно, не пробовал. Тоже хочу от етого зачититься.

Почему я толком не могу сказать что буду делать с многопоточностю. Потому что не могу сунуть контекст или другой обект содержащий в себе контекст в поле потока. Его оттуда достать легко если не сделать поле потока приватным и не защитить его менеджером безопасности. :)
А я biolashу обещал доступ к прайветам. (Я с ним вчера по аське поспорил что он не поломает).

63
31 января 2008 года
Zorkus
2.6K / / 04.11.2006
Цитата: Rebbit
Ну такое на мишине клиента я делать не собираюсь. Только на моей машине. На моем сервере.
Собственно я только что для себя сформулировал что меня интересует.
Смогу ли я сделать то что сказал в теме про синглетоныGreen ? Смогу ли я сделать так чтоб небыло глобальных данных вовсе? Только точка входа. Смогу ли я так роботать ? Защитит ли ето мои обекты от рефлексии ?


Да я тебе говорю, можно сделать простейшее веб-приложения, у которого вообще не будет метода main. Один сервлет, отображенный на какой-то URI. Выдающий что-то по запросу. Не вижу связи пока между точками входа и безопасностью доступа к синглтону. Пример приведи тогда уж.

Цитата: Rebbit

Во втором моем примере я не могу повредить своих обектов потомучто не могу до них добраться. Не знаю как получить инстанс. Могу создать новые, но зачем. Наверно могу визвать main повторно, не пробовал. Тоже хочу от етого зачититься.


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

Цитата: Rebbit

Почему я толком не могу сказать что буду делать с многопоточностю. Потому что не могу сунуть контекст или другой обект содержащий в себе контекст в поле потока. Его оттуда достать легко если не сделать поле потока приватным и не защитить его менеджером безопасности. :)
А я biolashу обещал доступ к прайветам. (Я с ним вчера по аське поспорил что он не поломает).


Что именно сломать надо? :) Может, я тоже присоединюсь. Заодно вдруг, найдем дыру в JVM, чем Гослинг не шутит.

276
31 января 2008 года
Rebbit
1.1K / / 01.08.2005
Цитата: Zorkus
Не вижу связи пока между точками входа и безопасностью доступа к синглтону. Пример приведи тогда уж.


Про точку входа ето я к слову. Просто хочу без глобальных переменных. Чтоб никто к моим обектам не добрался ;)

Цитата: Zorkus
Это пример с фабрикой? А почему нельзя их повредить-то? По крайней мере когда ты убрал финал у поля, хранящего инстанс у контекста. Что мешает загрузить класс этого контекста, и из него вытащить инстанс? В точности так же, как это делается для обычной реализации синглтона.


Ето в моих постах.
№12 я елементарно поломал синглетон. Просто и некрасиво.
№13 Изменения к псту №12. Переписал без синглетона. Нет синглетона и нет глобальных даных. Как достать инстанс из контекста ?
Инстанс синглетона можно достать с самого класса
[quote=Rebbit]

 
Код:
Method mGetInstance = cl.getDeclaredMethod("getInstance");
            ........................
            Object singleton = mGetInstance.invoke(null);

[/quote]
Етот null там не потому что параметров нет у гетИнстанс, а потому что метод статический. А метод Контекста гетПсевдоСинглтон не статический.

Цитата: Zorkus
Что именно сломать надо? Может, я тоже присоединюсь. Заодно вдруг, найдем дыру в JVM, чем Гослинг не шутит.


В Псевдосинглетоне строчку поменять. Буду рад если поломаете.

63
01 февраля 2008 года
Zorkus
2.6K / / 04.11.2006
Думаю, средствами рефлексии этого никак не сделать. Лезет в голову извращение - если сами данные строки известны точно, то ее можно поискать в памяти (heap) средствами JNI. Но это вряд ли станут делать авторы твоих игроков ;)
3.7K
04 февраля 2008 года
bioflash
169 / / 01.10.2005
Rebbit'у интересно как защитить свой код если он делает вызов чужого кода. Мне кажется ему просто нужно отказаться от этой идеи в таком виде как он собирается делать - если ти хочешь защитить свой код + тебе нужна взаимосвязь с чужим кодом - мне кажется тогда лучше задуматься об изменении своей архитектуры - может лучше использовать RMI или RPC. Просто переделать как-то интерфейс работы с чужим кодом.
276
04 февраля 2008 года
Rebbit
1.1K / / 01.08.2005
Цитата: Zorkus
Лезет в голову извращение - если сами данные строки известны точно, то ее можно поискать в памяти (heap) средствами JNI.


Я о JNI не знаю. Надо почитать. Но если есть такая возможность то впринцыпе можно тогда получить адресс объекта Class и сканировать кучу для поиска екземпляра етого класа. Полагаю что обект должен иметь ссылку на свой класс для поддержки виртуальных методов. Во всяком случае в .NET так и есть. Как в Java не знаю.

Цитата: bioflash
Rebbit'у интересно как защитить свой код если он делает вызов чужого кода. Мне кажется ему просто нужно отказаться от этой идеи в таком виде как он собирается делать - если ти хочешь защитить свой код + тебе нужна взаимосвязь с чужим кодом - мне кажется тогда лучше задуматься об изменении своей архитектуры - может лучше использовать RMI или RPC. Просто переделать как-то интерфейс работы с чужим кодом.


Я не собираюсь вызывать чужой код из своего в любом более-менне серезном проекте. Ето плохо и опасно. Но я хочу уметь делать такое. Ты можеш сказать что ето безполезная трата времени :). Но такой уж я есть. Хочу уметь и все.

63
17 февраля 2008 года
Zorkus
2.6K / / 04.11.2006
Читал тут Марка Гранда - Шаблоны проектирования в Java (http://wnk.biz/html/ru/contents190.htm - описание книги). В некотором роде адаптация накопленного опыта GoF. И вот, в разделе структурных паттернов нашел как раз тот, который мы тут обсуждали.
Dynamic Linkage. Загрузка по запросу и выполнение байткода класса, реализующего известный клиенту интерфейс. Т.е. как раз твой случай :).
Так вот, в области безопасности он примерно следующее говорит.
Цитата:

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

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог