Не AccessController.doPrivileged дает потокам JavaScript разрешения подписанного апплета?

Я смотрю на подписанный апплет, который сильно вызывается из JavaScript. Очевидно, что потоки, исходящие из JavaScript, более сильно изолированы, чем любой поток, запущенный непосредственно из Java. Например, если поток JavaScript вызывает в апплет и регистрирует что-то, что вызывает откат файла журнала, создается исключение безопасности. Любой поток, запущенный непосредственно в апплете, не будет испытывать это исключение безопасности. Решение здесь с log4j-это использовать асинхронный аппендер.

но с другими исключениями безопасности (например, использование оси Apache в подписанном апплете, но в потоке JavaScript) нет очевидного способа иметь некоторый асинхронный поток. Предположим, у меня есть следующий код, который при вызове из потока Java будет работать, а при вызове через JavaScript произойдет сбой с SecurityException:

public void someMethodCalledFromJavaScript() {
  // Stuff that would throw a SecurityException
}

Я вижу три варианта, но они не могут все быть в силе. Ради этого обсуждения игнорируйте независимо от того, будет ли выполнение синхронным или асинхронным, поскольку это легко управляется. Мне трудно понять детали модели безопасности. Вот мои три возможных варианта:--8-->

  • запустите новый поток (будет ли это работать?):

    public void someMethodCalledFromJavaScript() {
      new Thread(new Runnable() {
        public void run() {
          // Stuff that would throw a SecurityException
        }
      }).start();
    }
    
  • у апплета есть поток, готовый к работе в любое время, запускаемый через поток JavaScript-origin (сильно упрощенный код здесь):

    private volatile boolean doit = false;
    
    // This code is running in a Thread, started @ Applet init time
    public void alwaysWaiting() {
      while (true) {
        if (doit) {
          doit = false;
          // Stuff that would throw a SecurityException
        }
      }
    }
    
    public void someMethodCalledFromJavaScript() {
      doit = true;
    }
    
  • Используйте AccessController.doPrivileged:

    public void someMethodCalledFromJavaScript() {
      AccessController.doPrivileged(new PrivilegedAction() {
        public Object run() {
          // Stuff that would throw a SecurityException
          return null;
        }
      });
    }
    

по тому, что я читал о AccessController.doPrivileged, вы запускаете с пересечением текущих privs безопасности и privs домена безопасности кода, который вы вызываете. Это не имеет смысла для меня, как будто вы бежите с пересечение низкого и высокого уровня безопасности домена, вы будете просто иметь низкий уровень безопасности домена. Очевидно, я не понимание чего-то.

конкретные SecurityException Я вижу это:

java.security.AccessControlException: access denied (java.lang.RuntimePermission accessDeclaredMembers)

но, конечно, мне любопытно об общем случае в контексте JavaScript, вызывающего подписанный апплет, и как я могу позволить потоку, созданному JavaScript, работать с priv подписанного апплета, как если бы это был поток, который возник исключительно внутри апплета.

какие варианты выше будут даже работать, и которые лучше, чем другие, и почему.

2 ответов


  • "запустите новый поток (будет ли это работать?)"

не будет работать по причинам, упомянутым ниже

  • у апплета есть поток, готовый к работе в любое время, запускаемый через поток JavaScript-origin

будет работать, конечно, но это более болезненно, чем вызов doPrivileged, но имеет тот же эффект семантически.

  • Используйте AccessController.doPrivileged

Да это будет работать.

каждая проверка контроля доступа проверяет набор всех кадров стека в стеке текущего потока (включая кадр стека, ведущий к созданию экземпляра текущего потока, рекурсивно). Если есть doPrivileged кадр, кадры, ведущие к этому кадру, не включены в набор (но фактический doPrivileged рама is включил).

если проверяемая привилегия находится не в каждом кадре в этом наборе, проверка неудачи.

другими словами, текущие привилегии потока являются пересечением привилегий в этом наборе.

так, например, если привилегированный код doPrivilegeds какой-то непривилегированный код, который пытается открыть файл, проверка завершится неудачей. Аналогично, если непривилегированный код doPrivilegeds привилегированный код, который открывает файл, проверка завершится ошибкой. Но если непривилегированный код вызывает привилегированный код, а привилегированный код, в свою очередь, вызывает doPrivileged чтобы открыть файл, проверка будет преуспевать.

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

я никогда не делал JavaScriptJava interop, но кажется, независимо от того, что вам придется сделать методы, которые вызываются JavaScript use doPrivileged блоки на весь организм.


EDIT: как сами сказал, Быть осторожно при вызове doPrivileged блоки в привилегированном коде (и прочитайте его ответ).


Я бы пошел с doPrivileged. Просто имейте в виду, что все, у кого есть доступ к вашему апплету, могут загрузить его и поместить на свой сайт и иметь свой собственный вредоносный javascript, который вы не представляли.

последствия для безопасности других решений в значительной степени одинаковы (EDIT: хотя создание нового потока не работает, как указал Longpoke), но они сложнее. Так что я не вижу в них никакой пользы.

в AccessController.doPrivileged рассматривает домен защиты только непосредственного вызывающего абонента. В вашем примере класса, где ваш someMethodCalledFromJavaScript метод определен. Если это доверенный класс в подписанном jar, не имеет значения, что его вызывает ненадежный Javascript.