Mic,

I've taken the liberty to copy paste your questions into the list below (my apologies if I've missed some), my answers to your questions follow.

I'll apologise in advance, as I don't have time to answer more follow up questions, perhaps others on the list might be able to assist.

Regards,

Peter.

On 17/02/2017 10:23 AM, Michał Kłeczek wrote:
There is a huge misunderstanding here.

I am pretty confident I understand and know how River works (at least up to version 3.0 exclusive) And my questions are not about how things are implemented but what changes Peter is proposing. Especially in the context of all the discussions that are held here around security, OSGI, serialization etc.

The questions are very detailed and technical - because there is a lot of things that are not clear
in the proposed designs.

For example - saying that "deserializing an object is secure because
it is a dynamic proxy" is simply misleading. That is why I ask more questions.

I agree, that's a misleading statement, the words are not mine and I don't endorse that statement.


You might call it "demanding your time" but it shouldn't stop anyone from asking questions.

No, but there is a limit to how much time we might have available to answer them, in other words, try not to get upset if we don't.


Cheers,
Michal

I've noticed there are roughly three discussion topics in this conversation:

  1. Mic's SmartProxyWrapper - to Support OSGi, where it is proposed to
     use the wrapper object to perform codebase provisioning.
  2. JGDMS changes
  3. Formulating a proposal to support OSGi, leveraging delayed
     unmarshalling, resolving and provisioning a smart proxy bundle,
     without stream codebase annotations.

Mic's Questions:

  1.

     I want my implementation of RemoteEventListener to be a smart proxy.
     How do u support that?  Context - Supporting OSGi.

  2. If you allow to pass "installer" to unmarshall proxies - then the
     next question is - why do you require doing it explicitly in the
     application code???   Context - Supporting OSGi.
  3. But then the next question is why not put it in the object stream
     implementation itself???  Context - Supporting OSGi - using Mic's
     SmartProxyWrapper
  4. But what if the client has MULTIPLE clients - each with its own
     exact API version? Context - Supporting OSGi - clients with
     incompatible service api versions.
  5. So your SaveUnmarshallingProxy can do input validation fist as
     well, can't it? Context - I think it relates to JGDMS
  6. So if the CodeDownloadingSmartProxyWrapper implements AtomicSerial
     then it is fine? Context - Supporting OSGi - using Mic's
     SmartProxyWrapper.
  7. What is "signed codebase"? How do you encode the signature in the
     codebase annotation? Context - JGDMS
  8. Codebase of what service? All of them?
  9. Wouldn't it be easier if you simply forbid code downloading during
     unmarshalling as in SmartProxyWrapper I've shown in another
     message? Context - Supporting OSGi - using Mic's SmartProxyWrapper.
 10. Peter wrote:
      Some of your assumptions around forbidding code downloading are
      incorrect, which means the other assumptions that rely upon it
      are also wrong.
     Which assumptions?  Context - Supporting OSGi - using Mic's
     SmartProxyWrapper
 11. Is use of AtomicSerial mandatory?  Context - JGDMS
 12. Based on what information are DownloadPermissions and
DeserializationPermissions granted? Only URL of the jar file? Context - JGDMS
 13. It seems like I am missing the high level view on the architecture
     of your software.
     Would it be possible for you to write one? Context - JGDMS
 14. How does the client know it is "Reggie" it is talking to?  Context
     - JGDMS
 15. How Reggie can grant itself permissions in the client
     environment??? Context - JGDMS
 16. What is this "token"? Is it a Java object implementing a well
     known interface? What interface is it? Context - JGDMS
 17.

      SafeServiceRegistrar will still allow you to use your wrapper
      class, it just adds an additional step of allowing you to
      authenticate that service before you deserialize your service
      wrapper, making it a little safer.
     How???
     By using the "token" you talk about earlier? But you have to
     verify the token to be secure, don't you? Context - JGDMS
 18. So you delegate "token" authentication to Reggie, but that
     requires verification of Reggie proxy.
     But how do you verify Reggie proxy? Context - JGDMS
 19. Does Reggie also provide the "token"? If so - how is it
     authenticated? If not - how do you authenticate reggie? Context -
     JGDMS
 20.

      AtomicMarshalInputStream performs a special input validation on
      java.lang.reflect.Proxy thus ensuring the InvocationHandler is
      also trusted.  If the InvocationHandler doesn't pass the test
      the proxy's never created.
     Why does it only verify dynamic proxies? Doesn't it verify normal
     objects? Context - JGDMS
 21. Context - JGDMS
     1. What interface this bootstrap proxy implements?
     2. Why do you think it has to be a dynamic proxy (ie. an instance
     of a subclass of java.lang.Proxy)?
     3. What and when are DownloadPermissions required? How do they add
     to the overall security?
     I understand the security of service proxies is enforced by the
     constraints placed on the bootstrap proxy.
     So where is the place for DownloadPermissions?
 22. Context - JGDMS
     4. Finally - how is the lookup service proxy verified? Does it
     also provide the bootstrap proxy?
     If so - what special role does it play in the architecture?
     The bootstrap proxy does not have to be provided by the lookup
     service, does it?

     If it is verified differently - why and how?
 23. What I DO NOT understand is - why the download permissions are
     needed at all?
     Since the bootstrap proxy's code MUST be local code - why not
     simply have its class
     defined by the context ClassLoader?  Context - Existing River feature.
 24. Since downloading code is done only after authentication anyway -
     I don't see the reason to
     use DownloadPermissions at all.

     The only thing that comes to mind is that it is to make sure the
     service
     is not able to download code from a codebase different than its own.

     Which is OK but redundant. The reasoning is:
     Since the code of the service proxy is already trusted (we have
     established trust before downloading it) -
     we can simply place the constraints on the service proxy that
     instructs it to only download
     code meeting certain criteria.

     Am I correct in my thinking?  Context - requires clarification.


Pete's Answers:

  1. I'm not currently planning to support using remote objects (that
     aren't services) that require codebase provisioning for OSGi.  I'm
     presently only considering supporting remote Services (exported
     remote objects that are registered services).  Remote event
     listeners and such like that are dynamic proxy's only at this
     time, without a codebase.  My time is limited, if someone wants to
     implement it, then that's great.  Remember I haven't even begun
     coding this at this time, this is all very preliminary.
  2. Sorry, I've read it a few times, but still don't understand this
     question.
  3. The reason I don't think it's a good idea to put it in the stream
     is, what if it's missing?  The remote end controlls what's going
     into the stream, when you deserialize, you're only parsing it, the
     remote end controls which objects are placed into the stream, this
     is a lot riskier if you're not taking advantage of
     DownloadPermission.  But having said that, it's a strategy that
     would work, provided your utilising DownloadPermission and input
     validation.
  4. Each service api version released can have diffierent and multiple
     provider implementations, clients only need to know about the ones
     they're compatible with.
  5. Sorry JGDMS doesn't have this feature, the answer is therefore no.
  6. Yes you can use AtomicMarshalInputStream and perform input
     validation with your SmartProxyWrapper, then if your invariants
     aren't validated, the client can terminate the connection, the
     attacker loses control of the stream, an exception is thrown and
     control returns to the caller.
  7. A signed jar
https://docs.oracle.com/javase/tutorial/deployment/jar/signindex.html Httpmd can encode a message digest into your codebase annoation.
  8. Yes, I'd encourage you to sign all your jar files.  JGDMS allows
     you to use self signed code signer certificates, but you'll still
     need CA signed server and client certificates.
  9. I'm sorry, I can't find where you demonstrated how to forbid code
     downloading in SmartProxyWrapper.   DownloadPermission is an
     existing feature, and it's well proven, my personal opinion is it
     would easier to use that rather than write another tool that may
     create new vulnerabilities, but you are free to write one in
     SmartProxyWrapper if you want.
 10. I don't think you have a good understanding about how
     DownloadPermission works, you are proposing replacing it with a
     Serializable object in the stream with a class that's local to the
     client.  DownloadPermission is an existing feature of River, I
     think you need to perform some further investigation.
 11. No using AtomicSerial is not mandatory.  Some things are more
     exposed to attack, all existing River services utilise it in
     JGDMS, as do the token's and it is advisable to use it, however if
     you controll both ends of a secure endpoint (JGDMS TLSv1.2), then
     an attacker can't send you a serialized stream if your a service
     or a proxy.  But it's definitely necessary for Reggie and the tokens.
 12. These permissions are granted during discovery, after the lookup
     service is authenticated, the lookup service returns the URL
     string (can be null) and jar signer certificates (may be null) and
     these will be granted DownloadPermission and
     DeserializationPermission.  However these permissions will not be
     granted if both are null.    See hyperlinks below.
 13. Do you have any links of examples of what you're after?
 14. Reggie is authenticated, so you know it's Reggie you're talking
     to,  if Reggie can't be authenticated, we don't talk.
 15. If you use GrantPermission you can allow Reggie to grant
     permission to itself.  This isn't something that I'd encourage or
     condone however.  This is existing River functionality.  As
     mentioned above JGDMS first authenticates the connection to Reggie
     during discovery and only grants permission if authentication is
     successful.
 16. The token is an instanceof java.lang.reflect.Proxy, containing one
     of JERI's InvocationHandler's, the interfaces it implements are
     defined here:
     
https://github.com/pfirmstone/JGDMS/blob/Maven_build/modularize/JGDMS/jgdms-lib-dl/src/main/java/net/jini/lookup/SafeServiceRegistrar.java
 17. Yes, authentication occurs when the token makes a connection, you
     need to apply a minimum principal constraint.
 18. No, client authentication is not performed by reggie.  The
     client's proxy preparer performs authentication using the tokens
     retrieved from the lookup service.  ServiceDiscoveryManager is
     used in this instance to prepare the lookup service, the
     functionality in River that applies a proxy preparer to the lookup
     service is still there and utilised via configuration.
 19. Reggie's proxy retrieves the token from a service when it
     registers with the lookup service.  The authentication questions
     I've already answered above.
 20. java.lang.reflect.Proxy doesn't implement AtomicSerial, so it must
     be validated by AtomicMarshalInputStream, same goes for other
     utilised java platform classes.  Classes implementing AtomicSerial
     are responsible for validating their own invariants.
 21. .1 See the answer to question 16 above. 2. java.lang.reflect.Proxy
     appealed to me at the time, as it can utilise existing JERI
     endpoints for authentication.  3. DownloadPermission is part of
     the Jini platform, I've provided some answers already regarding
     DownloadPermission, I'll let you do some more investigation in
     your own time.
 22. Well, first the discovery process makes contact with the lookup
     service using the discovery protocol, then the lookup service is
     authenticated over a secure connection, then the lookup proxy is
     granted download permission and deserialization permission, to
     it's URL & signers, then it is downloaded, the proxy implements
     AtomicSerial and validates input.    The discussion about
     bootstrap proxy isn't relevant here.  The ProxyPreparer used by
     ServiceDiscoveryManager remains and has the same function as River
     / Jini.  The only change JGDMS makes in discovery is allow for
     DownloadPermission and DeserializationPermission to be granted
     dynamically after authentication.  There are some new discovery
     providers with improved security, but are just basically the same
     as River / Jini.
 23. I'll leave it as an exercise for you to investigate why
     DownloadPermission is required, this is part of River / Jini.
 24. Same as question 23 regarding DownloadPermission.

JGDMS shouldn't be seen as a new architecture, think of it as River with fixes for a number of security bugs and some neat features inspired by some long time River / Jini users who've expressed their ideas on the dev list, without whom, they wouldn't exist.

https://pfirmstone.github.io/JGDMS/
https://github.com/pfirmstone/JGDMS/blob/Maven_build/modularize/JGDMS/jgdms-discovery-providers/src/main/java/org/apache/river/discovery/internal/EndpointBasedServer.java
https://github.com/pfirmstone/JGDMS/blob/Maven_build/modularize/JGDMS/jgdms-discovery-providers/src/main/java/org/apache/river/discovery/internal/EndpointBasedClient.java
https://pfirmstone.github.io/JGDMS/doc/api/org/apache/river/discovery/ssl/sha224/package-summary.html
https://github.com/pfirmstone/JGDMS/blob/Maven_build/modularize/JGDMS/jgdms-discovery-providers/src/main/java/org/apache/river/discovery/ssl/sha256/package.html

Reply via email to