Java SecurityManager AccessControlException - Запуск от общего сетевого ресурса
У меня есть приложение Java 8, которое оценивает предоставленный пользователем код через Nashorn JavaScript ScriptEngine. Чтобы обеспечить защиту от оценки вредоносного кода, я включил Java SecurityManager со следующей политикой:
grant codeBase "file:/-" {
permission java.security.AllPermission;
};
grant {
permission java.net.SocketPermission "*", "accept,connect,resolve";
};
Это позволяет моему основному приложению Java работать без ограничений, но любой код JavaScript ограничен разрешениями, предоставляемыми через второй блок предоставления. Я упаковываю свое приложение в один файл MyApp.jar, и, вообще говоря, это работает нормально и вызывает AccessControlException каждый раз, когда кто-то пытается вызвать java.lang.System.exit()
из моего ScriptEngine и т. д.
Теперь о проблеме - если я помещу свой файл jar в общий сетевой ресурс (\\global\fs\Technology\Tools\MyApp.jar
) тогда мое приложение не загружается, так как блок гранта "AllPermission" не соответствует моей кодовой базе. Кто-нибудь еще сталкивался с этой проблемой и знает, как ее решить - это происходит только с сетевыми дисками, а не с другим местом, где я его разместил
Вот отладочный вывод -
java -Djava.security.manager -Djava.security.policy=mypolicy -Djava.security.debug=access -jar \\global\fs\Technology\Tools\MyApp.jar
Что приводит к следующим сообщениям об ошибках:
access: access allowed ("java.io.FilePermission" "\\global\fs\Technology\Tools\MyApp.jar" "read")
access: access allowed ("java.util.PropertyPermission" "os.version" "read")
access: access allowed ("java.util.PropertyPermission" "swing.useSystemFontSettings" "read")
access: access allowed ("java.util.PropertyPermission" "os.name" "read")
access: access allowed ("java.util.PropertyPermission" "java.home" "read")
access: access allowed ("java.io.FilePermission" "C:\Program Files\Java\jre1.8.0_121\lib\swing.properties" "read")
access: access allowed ("java.lang.reflect.ReflectPermission" "suppressAccessChecks")
access: access allowed ("java.util.PropertyPermission" "os.version" "read")
access: access allowed ("java.util.PropertyPermission" "user.dir" "read")
access: access allowed ("java.io.FilePermission" "C:\etc\release" "read")
access: access allowed ("java.io.FilePermission" "\etc\release" "read")
access: access allowed ("java.util.PropertyPermission" "swing.showFromDoubleBuffer" "read")
access: access allowed ("java.util.PropertyPermission" "swing.nativeErase" "read")
access: access denied ("java.awt.AWTPermission" "showWindowWithoutWarningBanner")
access: access allowed ("java.util.PropertyPermission" "awt.appletWarning" "read")
access: access allowed ("java.util.PropertyPermission" "java.home" "read")
access: access allowed ("java.util.PropertyPermission" "sun.awt.nopixfmt" "read")
access: access allowed ("java.util.PropertyPermission" "swing.logDoubleBufferingDisable" "read")
access: access allowed ("java.util.PropertyPermission" "swing.ignoreDoubleBufferingDisable" "read")
access: access allowed ("java.lang.RuntimePermission" "createClassLoader")
access: access allowed ("java.lang.RuntimePermission" "createClassLoader")
access: access allowed ("java.lang.RuntimePermission" "accessClassInPackage.sun.reflect.misc")
.. (removed for brevity)
access: access allowed ("java.util.PropertyPermission" "os.name" "read")
access: access allowed ("java.util.PropertyPermission" "java.util.prefs.PreferencesFactory" "read")
access: access allowed ("java.util.PropertyPermission" "os.name" "read")
access: access allowed ("java.lang.reflect.ReflectPermission" "suppressAccessChecks")
access: access denied ("java.lang.RuntimePermission" "preferences")
Exception in thread "AWT-EventQueue-0" java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "preferences")
at java.security.AccessControlContext.checkPermission(Unknown Source)
at java.security.AccessController.checkPermission(Unknown Source)
at java.lang.SecurityManager.checkPermission(Unknown Source)
at java.util.prefs.Preferences.userRoot(Unknown Source)
at e.<init>(Unknown Source)
at e.<init>(Unknown Source)
at MyApp.<init>(Unknown Source)
at a.run(Unknown Source)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$500(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
Я даже пытался ссылаться на codeBase точно так же, как описано выше, но у меня все еще есть те же проблемы:
grant codeBase "file:\\global\fs\Technology\Tools\MyApp.jar" {
permission java.security.AllPermission;
};
ОБНОВЛЕНИЕ Дальнейшая отладка показала, что выглядит как ошибка в Java?? Я сопоставил "Active CodeSource" точно в файле политики, и он все еще отклоняет его:
grant codeBase "file:/-" {
permission java.security.AllPermission;
};
grant codeBase "file://global/fs/Technology/Tools/MyApp.jar" {
permission java.security.AllPermission;
};
grant {
permission java.net.SocketPermission "*", "accept,connect,resolve";
};
С policy
отладка, я вижу следующее (я замечаю, что file:/-
изменения разрешают только мой текущий диск C:):
C:\Users\Default> java -Djava.security.manager -Djava.security.policy=mypolicy -Djava.security.debug=policy -jar \\global\fs\Technology\Tools\MyApp.jar
policy: evaluate codesources:
Policy CodeSource: (file:/C:/- <no signer certificates>)
Active CodeSource: (file://global/fs/Technology/Tools/MyApp.jar <no signer certificates>)
policy: evaluation (codesource) failed
policy: evaluate codesources:
Policy CodeSource: (file://global/fs/Technology/Tools/MyApp.jar <no signer certificates>)
Active CodeSource: (file://global/fs/Technology/Tools/MyApp.jar <no signer certificates>)
policy: evaluation (codesource) failed
policy: evaluate codesources:
Policy CodeSource: (null <no signer certificates>)
Active CodeSource: (file://global/fs/Technology/Tools/MyApp.jar <no signer certificates>)
policy: evaluate principals:
Policy Principals: []
Active Principals: []
policy: granting ("java.net.SocketPermission" "*" "connect,accept,resolve")
Как вы можете видеть, он сравнивает "Policy CodeSource" с "Active CodeSource" и говорит, что они не совпадают, даже если они идентичны?!? Поскольку они не совпадают, это падает на мой общий блок предоставления, который только предоставляет ограниченные разрешения.
Это происходит только в том случае, если мой текущий рабочий каталог находится на другом диске или файловой системе, чем мой JAR-файл.
Разве невозможно предоставить разрешения для "MyApp.jar" независимо от пути?