avalon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Berin Loritsch <blorit...@apache.org>
Subject Re: [VOTE] ComponentValidator
Date Wed, 05 Dec 2001 14:34:30 GMT
Peter Donald wrote:

> On Wed, 5 Dec 2001 00:53, Berin Loritsch wrote:
> 
>>Berin Loritsch wrote:
>>
>>>Peter Donald wrote:
>>>
>>>>On Tue, 4 Dec 2001 08:37, Berin Loritsch wrote:
>>>>
>>>>>The ComponentValidator code has been fixed yet again.  It's real home
>>>>>belongs in Framework, and I propose to move it to Framework in the
>>>>>following package:
>>>>>
>>>>>org.apache.avalon.framework.component.ComponentValidator
>>>>>
>>>>>This tool is used to verify the contracts of a Component's life
>>>>>cycle.  It
>>>>>is invaluable for development.  Do not vote in the negative if you just
>>>>>want to be a PITA, or if you will not use it.  Vote in the negative if
>>>>>there is some stronger architectural or design issue at steak.
>>>>>
>>>>-1
>>>>It encourages bad practices - as exhibited by your dangerous fantasy
>>>>that this will somehow make the application more secure.
>>>>
>>I want you to understand exactly the type of attack that this Component
>>protects against with minimal overhead:
>>
> 
> I am quite aware of your opinion which is exactly why I used the term 
> "dangerous fantasy".


We all know there are different levels of protection.  However, there are
more reasons than just protecting against the attack I displayed in my
previous message.  I will address the levels below on your discussion of
UNIX file permissions.

The main issue is forcing correctness.  Since we are not creating JDK 1.4
compliant code right now, we can't take advantage of Assertions.  You seem
to be in favor of assertions, however you are against this validator that
provides some very specific assertions with minimal overhead.  The thing
is, explicit casting is expensive in Java.  The JVM needs to get a handle
on the Class, look up the interfaces/classes that are implemented/extended,
and then determine if it is possible to perform the cast.  If we use
assertions, we would be spreading the cost of that lookup to every invokation
of the lifecycle methods.

Taking this one step further, so that _when_ we do directly support assertions,
we can minimize the cost of keeping them on.  For instance, the following
snippet (scope omitted for clarity):

class MyComponent implements Component, Composable
{
     ComponentValidator m_validator;
     ComponentManager   m_manager;

     MyComponent()
     {
         assert m_validator = new ComponentValidator(this);
     }

     void compose( ComponentManager manager )
     {
         assert m_validator.checkAssigned(m_manager);
         assert m_validator.checkComposed();

         m_manager = manager;
     }
}

There, the existence of the validator is only there when assertions are enabled.
That way, when assertions are turned off, the Validator and it's checks are
not performed.  This also are well behaved assertions in that there are no
side-effects to require them to be turned on.

Also, the existence of the ComponentValidator allows engineers (since they will
insist on performing these validations) to implement their checks correctly--
without reinventing the same wheel in several Components.

During the interim where assertions are _not_ supported yet, these provide an
almost invisible way of performing the assertions in a run-time system.  They
are about as costly as using LogKit with the logger.isXXXenabled() methods.

We might want to add validator.isComposed(), etc. methods to the class so that
assertions are more correct (they test booleans).

For instance, this would be correct:

assert m_validatory.isAssigned(m_manager);
assert m_validator.isComposed();

While the .checkXXX() methods are necessary in the absence of assertions.


>>Validating lifecycle is absolutely critical in an environment where
>>Components are pluggable and dynamically loaded.  Should it replace other
>>basic tenets of security like never loading a Component you don't know? 
>>Never.  However, such an approach *minimizes* the number of things a
>>maliscious Component can do if it somehow gets itself loaded in the
>>environment.  It is very much analogous to UNIX file permissions in that
>>they are not in and of themselves security, however they help to minimize
>>damage once security is breached.
>>
> 
> Lets go with your UNIX file permissions analogy. 
> 
> * Containers in Avalon are analogous to the kernel


They are more analogous to programs.  I will elaborate a little more later.


> * Components are analogous to processes
> 
> One a kernel is breached it matters little what UNIX file permissions are 
> assigned to a particular user/group because they can just change users or 
> grab what ever perms they feel like. I could translate into java terms but 
> you get the idea


I am not arguing that point.  However, it is more difficult to get 'root'
access than breach a specific program.  The practice of running web services
(like the HTTP server) as a user is so that if the program/service is
compromized, the attacker has the permissions of that service.  For instance,
if Apache was running as 'nobody', and someone managed to crack it, and get
access to the machine through that service, they would have the priveleges of
the 'nobody' user.  Running the http esrver as 'root' is like asking a hacker
to take control of your machine because you are masochistic.

There are ways of gaining root access at this point, however it is not as easy
as doing it when the server is running as root.  Also, as Leo pointed out, the
File Permissions are to protect users from themselves more than they are to
protect against hackers.  For instance, just because someone can type in the
infamous command `rm -rf /` does not mean that the system should allow the
user to wipe out any files they are not supposed to.

> Continuing on with the analogy, you are trying to protect applications in the 
> case where the kernel does not implement proper isolation. Lets say there is 
> no such thing as memory protection between applications - anyone who has 
> written code in an environment like that knows there is very little you can 
> do to protect your app in a sitation like that where an "evil" application 
> decides to mess with your app.


Let me ask you, is it the Container's responsibility to detect when a Component
is obtained and cast as a Composable?  Implementing such a beast is pretty
complex, and more than likely, the cost of proxying the Component outweighs
it's usefullness.  For Blocks, it is a different story.  They require that
extra level of security.

But let me bring in one more valid point.  We have the pattern of Inversion
of Control and its antipattern Subversion of Control.  The ComponentValidator
makes it more difficult to subvert the control of a Component.  It's not
impossible, but it is more difficult.  It encourages proper use of a Component.

Checks should not _only_ be performed on the server side (of a client/server
application or in this case container/component), but _ideally_ on the client
side as well.

The FullLifeCycle Component used to test the ComponentValidator is the perfect
tool to *also* test proper Containers.  It will throw an exception if the
initialization is not in the proper order.  While it would *technically* be
possible to do the same thing without the ComponentValidator, the Validator
is a good tool to provide assertions at low cost while there are no language
features available.




-- 

"They that give up essential liberty to obtain a little temporary safety
  deserve neither liberty nor safety."
                 - Benjamin Franklin


--
To unsubscribe, e-mail:   <mailto:avalon-dev-unsubscribe@jakarta.apache.org>
For additional commands, e-mail: <mailto:avalon-dev-help@jakarta.apache.org>


Mime
View raw message