You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@river.apache.org by Peter Firmstone <ji...@zeus.net.au> on 2010/01/28 07:21:27 UTC

Security, Trust and a few ideas.

Contrary to popular belief, it is my opinion that distributed object 
systems, have the potential to be more secure than those using message 
passing alone

Consider the following potential future scenario:

   1. We set up a public source code verification and bundle signing
      site, codebase servers consume and dispense the compiled and
      signed bundles (jar files).
   2. Package Version metadata is added to MarshalledObject
   3. An RMIClassLoaderSPI is implemented to organise ClassLoader
      PackageVisibility, limited to bundle package dependencies.
   4. Each bundle (jar) contains the Permissions required (Permissions
      are limited to this list and are granted only after code has been
      checked by the security manager).
   5. OSGi Conditions require specific sets of conditions to be
      satisfied before specific Permissions are granted by the Security
      Manager.  You might require more than one trusted signature before
      granting a piece of code sensitive permissions.
   6. DNSSEC, DNS-SD, DNS Dynamic Update (insert other DNS buzzwords
      here) is utilised by a new GlobalLookupService to take services
      global.


Why could it be more secure than the conventional internet? 

Consider this; a chain is only as strong as its weakest link, we'd be 
using wire rope, breaking a strand won't break the system.

What's this gobble-de-gook?

Well, if you discover a global lookup service, it's code has to be 
signed by a trusted entity, the open source code validation model 
doesn't depend upon trust chains or obscurity, just openly visible 
source and compiled bundles anyone can sign. If someone else signs the 
bundle, you both have a source code contract on which to interact.  You 
don't even have to trust the other party.  To update the DNS-SD your 
proxy must be verified by a GlobalLookup service, your verified proxy 
sends the DNS update packets to the the GlobalLookup which signs the 
packets and forwards them to a DNS-SD server.

Now if your service download bundle isn't signed, or your client looks 
it up from a codebase service provided by a cacker, it is stopped by the 
security manager when attempting to load the code.  If a signed bundle 
is available from a codebase service that matches the closest Package 
version from MarshalledObject, then this valid code is used to 
communicate with you by the client instead.  You still need to validate 
the proxy however.

If the DNS-SD cache has been poisoned to redirect you to a malicious 
service implementation, then you are protected by the validated code in 
the signed download bundle and restricted to the permissions and 
conditions related to it as enforced by the SecurityManager.  The 
Service is very limited in what attacks it can perform on the client, 
and when one is discovered, the signed bundle can be updated and the 
offending package version can be incremented and avoided.  The code can 
be updated dynamically by reloading a proxy with the latest code.

The weakest strand is the Service, in validating the proxy with the 
Trust Verifier, any thoughts on this?

Of course not everybody likes to implement security, however if the 
GlobalService depends upon security to function, then those who are 
insecure (by just accepting any signed code without auditing) don't 
jeopardise those who are.

Now if you're really pedantic, you'll have realised that the standard 
x86 architecture is insecure and being free to choose, you'll have 
another architecture with a secure OS like OpenBSD for your critical 
clients and services.

I believe the potential is there to have a system that is more secure 
than one that just utilises message passing.

Why, what are the potential benefits?

    * Signed open and audited shared code with integrity checking; a
      communication contract.
    * Codebase services that dispense signed audited security updates,
      so your code is always up to date.
    * Conditions (OSGi) that may dynamically change the state of a
      permission, as soon as a vulnerability has been identified, the
      permission required can be denied until updated code is received.
    * Secure communication channels
    * Pools of Trust chains, but no overarching controlling trusted entity.
    * Global roaming.
    * Distributed Objects that are untethered from their original
      Service by codebase services with new URL identifiers.

Now consider the current alternative:

   1. You open a browser and log into your favourite https internet bank
      site with your Kerberos security token (mailed to you by the bank).
   2. Your browser window shows a padlock and validates the Server
      certificate from the domain owned by the cracker.
   3. At this point in time, you are unaware that your the victim of a
      DNS cache poisoning attack, you've been redirected to a crackers
      site. (where a whole domain not just the site has been cracked
      using the Kaminsky attack)
   4. You've unwillingly just logged into the wrong site, the cracker
      site logs into the bank's real site and does your banking for you,
      using your login and the security token's hash you've so kindly
      just provided.

The danger in using DNSSEC alone, is that even it is still vulnerable as 
it has to make performance based compromises, as it is a link in a 
message passing system's chain.

All journey's begin with a single step, if you've ever walked long 
distance, you'll know that by placing one foot in front of the other, 
without worrying about the journey and enjoy the stops on the way, 
you'll get there.

Some steps in the journey, grouped into separate independent groups.

   1. Create a new URL type.
   2. Create a new extensible Factory for our URL type.
   3. Set up a simple codebase service implementation.
   4. Implement a RMIClassLoaderSPI that either instantiates or embeds
      the OSGi framework
   5. Alter MarshalledObject to include the class package version (when
      it exists)
   6. Create some separate server, interface and optional client bundles
      (only for smart proxy's).
   7. Identify simple proxies and make sure they're loaded via the
      interface bundle Classloader at the client to avoid additional
      ClassLoaders or visibility problems.
   8. Look into tools to assist with bundle creation.
   9. Document bundle packaging principles.
  10. Convert existing service implementations to bundles.

   1. Alter LookupLocator to accept a configurable Factory
   2. Create a GlobalServiceLookup implementation that utilises DNS-SD
      and JERI.
   3. Experiment with implementations.
   4. Look into firewall traversal issues.
   5. Look into the security mechanisms supported by DNS-SD and how to
      support these via the GlobalServiceLookup.

   1. Set up an open code auditing area for interfaces, client proxy
      code and Proxy trust verifiers and bundles signing, and any other
      code that might be useful to share.
   2. Test it, look for some simple contributions.

   1. Set up a small public domain that hosts some public services
      discoverable via DNS-SD.
   2. Experiment with Security Conditions and Policies.


Cheers,

Peter.