Как обеспечить безопасность Java для пакетов из белого списка с помощью диспетчера безопасности Java?

Проблема: я пытаюсь ввести ограничение (занести в черный список) все и разрешить только то, что предоставил, когда мы выполняем groovy с помощью GroovyClassLoader.

Я могу выполнять пользовательскую политику с ограниченным разрешением только для GroovyClassLoader.

Теперь я пытаюсь предоставить ограничение пакета, которое будет использоваться как часть выполнения groovy. Скажем, если я разрешил com.x.y этот пакет, если какой-либо пакет, отличный от этого, используемый в groovy, должен вызвать SecurityException

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

    public TestSecurityManager extends SecurityManager{

    List<String> whiteListedPkgList;

     public void checkPackageAccess(String pkg){
         if(!pkg.startWith(any of given white list pkg)){
           throw new SecurityException("Access Denied");
           }
        //If package not belong to whilelisted package list throw security exception
       }
    }

Когда я пытался использовать описанный выше подход, нам нужно предоставить все пакеты для выполнения например, com, java и т. д. вместо java.nio.file. в белом списке

ОБНОВЛЕНИЕ

Если мы попытаемся разрешить такой пакет, как com.x.y, используя сравнение белого списка, используя запуск с проверкой доступа pkg, он разрешит этот пакет, но позже он выдаст исключение безопасности для < пакет strong>com.

Может ли кто-нибудь помочь тому же, как мы можем этого достичь?

заранее спасибо


person Ranjitsinh    schedule 28.01.2020    source источник
comment
Не могли бы вы добавить конкретный пример, который не работает или который вы хотели бы улучшить (например, что в вашем белом списке и какие pkg значения не работают должным образом)   -  person cfrick    schedule 28.01.2020
comment
Пожалуйста, найдите обновленную информацию и пример кода.   -  person Ranjitsinh    schedule 29.01.2020


Ответы (1)


Если вы можете вместо использования Java SecurityManager использовать функции Groovy DSL, вам будет проще добиться этого.

См. https://www.groovy-lang.org/dsls.html#_secure_ast_customizer

Пример:

import groovy.transform.CompileStatic
import org.codehaus.groovy.control.CompilerConfiguration
import org.codehaus.groovy.control.customizers.CompilationCustomizer
import org.codehaus.groovy.control.customizers.SecureASTCustomizer

@CompileStatic
class Main {
    static final CompilationCustomizer scz = new SecureASTCustomizer().with {
        closuresAllowed = false // user will not be able to write closures
        methodDefinitionAllowed = false // user will not be able to define methods
        importsWhitelist = [] // empty whitelist means imports are disallowed
        staticImportsWhitelist = [] // same for static imports
        staticStarImportsWhitelist = ['java.lang.Math'] // only java.lang.Math is allowed
        constantTypesClassesWhiteList = [
                Integer,
                Float,
                Long,
                Double,
                BigDecimal,
                Integer.TYPE,
                Long.TYPE,
                Float.TYPE,
                Double.TYPE,
                Object,
                String,
        ].asImmutable() as List<Class>
        // method calls are only allowed if the receiver is of one of those types
        // be careful, it's not a runtime type!
        receiversClassesWhiteList = [
                Math,
                Integer,
                Float,
                Double,
                Long,
                BigDecimal,
                PrintStream,
                Object,
        ].asImmutable() as List<Class>

        it
    }

    static void main(args) {
        def configuration = new CompilerConfiguration()
        configuration.addCompilationCustomizers(scz)

        // evaluate sandboxed code
        new GroovyShell(configuration).evaluate(
                """ println 'hello world' """)
    }

}

Если все, что вам нужно, это внести определенные классы в белый список, вы также можете попробовать написать свой собственный загрузчик классов и использовать его для оценки изолированного скрипта:

class MyClassLoader extends ClassLoader {

    Set<String> whiteListPackages = [
            'java.lang.', 'java.util.', 'groovy.', 'org.codehaus.groovy.', 'Script'
    ]

    MyClassLoader(ClassLoader parent) {
        super(parent)
    }

    @Override
    protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
        if (!whiteListPackages.any { okPkg -> name.startsWith(okPkg) }) {
            throw new ClassNotFoundException('Access is forbidden')
        }
        return super.loadClass(name, resolve)
    }
}

def shell = new GroovyShell(new MyClassLoader(GroovySystem.classLoader))

// evaluate the script with our own classloader
shell.evaluate('''
println 'hello'
println([1,2,3])

// This line throws an error because the `java.net` package is not whitelisted
println(new URL('https://groovy-lang.org'))
''')
person Renato    schedule 28.01.2020
comment
Спасибо за ответ ! Я пробовал то же самое, но обнаружил следующие проблемы. 1.) Он не позволяет использовать подпакеты. Например, если вы добавите пакет xy в белый список, он не разрешит подпакет xyz. 2.) он не сможет идентифицировать пакеты, если мы используем внешний jar с помощью загрузчика классов в groovy. - person Ranjitsinh; 29.01.2020
comment
если вас интересуют только пакеты используемых классов, вам просто нужно реализовать и использовать свой собственный загрузчик классов... довольно просто. Опубликует еще один ответ, показывающий, как это сделать. - person Renato; 29.01.2020
comment
Мне нужно ограничение не только для используемых пакетов, но и для другого компонента. например, если я разрешу доступ только для чтения файла для любого места, но не для записи и удаления и т. д. - person Ranjitsinh; 30.01.2020
comment
Было бы здорово, если бы вы могли предоставить способ ограничить определенный метод любого класса с помощью DSL. - person Ranjitsinh; 30.01.2020
comment
чтобы ограничить такие методы, просто представьте свои собственные типы сценарию, который реализует любое ограничение, которое вы хотите. - person Renato; 30.01.2020
comment
Не могли бы вы привести пример, который вы предложили для собственного загрузчика классов? - person Ranjitsinh; 17.02.2020
comment
Добавил пример в ответ. - person Renato; 18.02.2020
comment
Спасибо ! Я проверил добавленный пример, но это не поможет в случае, если мы используем внешний класс ссылки jar в groovy. Есть идеи, как мы можем заблокировать используемый класс во внешнем файле jar? - person Ranjitsinh; 24.02.2020
comment
Этот пример уже может это сделать... что именно вы имеете в виду, что не можете заблокировать?? - person Renato; 24.02.2020
comment
Это не сработает для меня. Причина в том, что я динамически генерирую свой классный класс, используя метод класса синтаксического анализа GroovyClassLoader вместо метода loadClass. Я хотел ограничить класс, используемый в groovy, который исходит из внешних ссылок на файлы jar. - person Ranjitsinh; 24.02.2020
comment
Я могу ограничить пакеты, но теперь хотел заблокировать/предотвратить доступ к определенному классу для данного доступа к пакету для выполнения groovy. Groovy DSL работает только во время компиляции, а не для внешней ссылки на банку - person Ranjitsinh; 24.02.2020
comment
Вы должны задать это в новом вопросе с примером кода, показывающим, что именно не работает. - person Renato; 24.02.2020