River
  1. River
  2. RIVER-362

Denial of Service during unmarshalling of smart proxy's

    Details

    • Type: Bug Bug
    • Status: Open
    • Priority: Major Major
    • Resolution: Unresolved
    • Affects Version/s: None
    • Fix Version/s: None
    • Component/s: None
    • Labels:
      None
    • Environment:

      Untrusted networks

      Description

      During unmarshalling of smart proxy's there's a period before the proxy has been verified (authenticated) where deserialization methods are executed on untrusted code, the potential exists for untrusted code to perform denial of service.

      1. river-modules.zip
        92 kB
        Michal Kleczek

        Issue Links

          Activity

          Hide
          Michal Kleczek added a comment -

          I've managed to create a prototype implementation of the idea of annotating
          classes with Modules.
          Working on this allowed me to learn quite a lot about inner workings of River

          • the original implementation that I've presented before had to be modified
            (not saying it had to be fixed ) but the main idea stayed the same. This
            time I think it really covers more use cases.

          Shortly:
          1. We allow annotating classes with Modules. A Module is an object responsible
          for loading classes.
          2. There is a new RMIClassLoaderSpi implementation which I called
          ModuleClassProvider
          3. ModuleClassProvider manages installed Modules
          4. It also can load classes based on String annotations which are expected to
          be either
          a) serialized and Base64 encoded Module - the Module is deserialized and
          handled as any other Module annotation
          b) an old style list of URLs - class loading is delegated to
          RequireDlPermProvider - in other words we either load classes from Modules
          (which are verified for trust before use) or from URLs but then we require
          appropriate DownloadPermissions

          Attached is a multi-module maven project. The modules are:
          1. secure-marshall-stream (which is the implementation of all this + some not
          yet finished additional code)
          2. jsk-module-platform which contains modified Jini classes so that it all
          works with existing Jini services (to be honest only ClassLoading really
          needed to change. MarshalInputStream/MarshalOutputStream/MarshalledInstance
          are changed only to avoid having serialized and Base64 encoded Modules as
          annotations

          To run it you need to put jsk-module-platform before jsk-platform on the
          classpath (and of course add secure-marshall-stream as well)

          Existing services can be exported with a ModuleExporter:

          private serviceILFactory =
          new ProxyTrustILFactory(serviceConstraints,
          RegistrarPermission.class);
          private moduleTrustILFactory =
          new ModuleTrustILFactory(serviceConstraints,
          null);

          serverExporter = new ModuleExporter(new BasicJeriExporter(serviceEndpoint,
          serviceILFactory), new BasicJeriExporter(serviceEndpoint,
          moduleTrustILFactory));

          Show
          Michal Kleczek added a comment - I've managed to create a prototype implementation of the idea of annotating classes with Modules. Working on this allowed me to learn quite a lot about inner workings of River the original implementation that I've presented before had to be modified (not saying it had to be fixed ) but the main idea stayed the same. This time I think it really covers more use cases. Shortly: 1. We allow annotating classes with Modules. A Module is an object responsible for loading classes. 2. There is a new RMIClassLoaderSpi implementation which I called ModuleClassProvider 3. ModuleClassProvider manages installed Modules 4. It also can load classes based on String annotations which are expected to be either a) serialized and Base64 encoded Module - the Module is deserialized and handled as any other Module annotation b) an old style list of URLs - class loading is delegated to RequireDlPermProvider - in other words we either load classes from Modules (which are verified for trust before use) or from URLs but then we require appropriate DownloadPermissions Attached is a multi-module maven project. The modules are: 1. secure-marshall-stream (which is the implementation of all this + some not yet finished additional code) 2. jsk-module-platform which contains modified Jini classes so that it all works with existing Jini services (to be honest only ClassLoading really needed to change. MarshalInputStream/MarshalOutputStream/MarshalledInstance are changed only to avoid having serialized and Base64 encoded Modules as annotations To run it you need to put jsk-module-platform before jsk-platform on the classpath (and of course add secure-marshall-stream as well) Existing services can be exported with a ModuleExporter: private serviceILFactory = new ProxyTrustILFactory(serviceConstraints, RegistrarPermission.class); private moduleTrustILFactory = new ModuleTrustILFactory(serviceConstraints, null); serverExporter = new ModuleExporter(new BasicJeriExporter(serviceEndpoint, serviceILFactory), new BasicJeriExporter(serviceEndpoint, moduleTrustILFactory));
          Hide
          Peter Firmstone added a comment -

          In the Module interface, instead of passing ClassLoader instances to the Module, I'd recommend passing a GuardObject, which contains the ClassLoader, since the permission check for the RuntimePermission("getClassLoader") may be performed prior to the Module's ProtectionDomain existing on the call stack.

          This would also allow the Module to delegate to other code, that performed the ClassLoading on it's behalf, if the Module doesn't have sufficient permission to do so itself.

          Show
          Peter Firmstone added a comment - In the Module interface, instead of passing ClassLoader instances to the Module, I'd recommend passing a GuardObject, which contains the ClassLoader, since the permission check for the RuntimePermission("getClassLoader") may be performed prior to the Module's ProtectionDomain existing on the call stack. This would also allow the Module to delegate to other code, that performed the ClassLoading on it's behalf, if the Module doesn't have sufficient permission to do so itself.
          Hide
          Peter Firmstone added a comment -

          The DOS attack can be fixed by limiting the classes permitted for deserialization to those local classes required to authenticate the verifier proxy.

          http://www.ibm.com/developerworks/java/library/se-lookahead/index.html

          The verifier proxy can be deserialized from the stream using local code, by searching the stream for its class, then after authentication, the verifier proxy can be used to verify the stream. During stream deserialization any references to the verifier proxy (eg by the smart proxy) need to be updated.

          Show
          Peter Firmstone added a comment - The DOS attack can be fixed by limiting the classes permitted for deserialization to those local classes required to authenticate the verifier proxy. http://www.ibm.com/developerworks/java/library/se-lookahead/index.html The verifier proxy can be deserialized from the stream using local code, by searching the stream for its class, then after authentication, the verifier proxy can be used to verify the stream. During stream deserialization any references to the verifier proxy (eg by the smart proxy) need to be updated.

            People

            • Assignee:
              Unassigned
              Reporter:
              Peter Firmstone
            • Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

              • Created:
                Updated:

                Development