Guide to Defensive programming

 

(this is work in progress)

 

How to write code that is secure in the SecureSqueak environment.

 

There are several types of security leaks possible:

 

  • Private objects should not be returned from a method or block invocation or passed in parameters to another untrusted object.
  • Method invocations on untrusted objects may never return.
  • Some methods of a class might be private. These must not be callable from outside that class.

 

Blocks might be secure: having a reference to a block only lets the reciever evaluate that block and does not give access to private variables in that block's context (currently in non-closure Squeak, this also includes local variables in that block's containing MethodContext). Evaluating a block from an untrusted source does not give that block access to local vars, but the invocation may not return.

 

Methods currently end in ^self unless some other return argument is given. This might make the method insecure - the compiler will need to be modified to alert the user if the user forgets to add a return statement in a private object's method. This is particularly important with blocks - the result of the evaluation of the last statement in a block is returned when the block is evaluated. This is a possible security leak. Perhaps the compiler should warn the user or some special syntax should be used? "[ someThing someValue returnFromBlock ].", cf: "[someThing someValue. nil.]". This only matters if the block is accessed outside the current method. (Alternatively, the IDE could issue a warning).

 

[heh? Why is returning "self" a security risk? Surely if a message can be sent, the sender must have a reference to that object... ]

 

Method invocations on untrusted objects that may block could be managed using "[...] fork", futures or perhaps with a fancy inter-domain timeout?

 

Proxy objects (probably called "Interfaces") containing a secure sub-set of methods on an object could be returned. Every method on these "Interfaces" would directly invoke a method on it's target object (the original object).

 

Private methods could be defined, but would only be able to be checked at run-time: "Method private." would throw an AccessDeniedException if the method is invoked by anybody other than self. The VM could be modified to be fast for this.

 

 

  • Return gates / cages / proxies (or whatever) to your object from all your methods.
  • Beware of method invocations on external, untrusted objects. They may block indefinitely.
  • Be wary of passing a block to an untrusted object.
  • If blocks are passed outside your object, make sure their return value is not "self" or something that could be a security leak.
  •  

 

Patterns

 

  • The gate / proxy / cage / guard. These limit the API available, and can be disconnected.
  • read-only objects with a flag.
  • Capabilities with a back-door to the object's instvars.
  • Private methods.
  • Methods that verify their sender or the capabilities of the sender.
  • fork off method calls on untrusted objects to prevent no return.
  • dominion encapsulation - make sure you don't leak your dominion.

 

 

How would you initialize a read-only object?

 

You can't use a normal constructor to send instvars because then the object wouldn't be read-only.

 

  • Use capabilities or check the sender of the setting method?
  • Use primitives to set instvars directly from outside?

 

--> Easy - have a read-only flag in the object. When initialised, the flag is false. The constructor then sets all the arguments using setter methods. When done, the flag is set to true and cannot be unset. The setter methods check for the value of this flag and cause an error if attempts are made to modify the object when in "read-only" mode.

 

 

Special APIs

 

(work in progress)

 

Dominions are available:

 

self dominion.  "return my dominion, only callable by self."

self hasCapability: SomeCapability...

self dominion cpuSpeed < 150 ifFalse: [...].

 

A special "sender" global variable is available. This has access to thisContext (whereas other code doesn't) and can verify who the caller is:

 

(sender = someObject) ifTrue: [...].

(sender hasCapability: someCapability) ifTrue: [...].

sender isKindOf: aClass...

sender isMemberOf: aClass... "less useful if multiple versions of that class are available.

sender implements: aClass...  " throws an exception, or should it return true/false? "

sender mustBeSelf. "Private method. "

 

A mechanism for declaring types of objects will be implemented.

 

myObject isA: SomeClass. "Throws an exception if not. "

myObject implements: SomeInterface. "Throws an exception if not. Hmm... looks like it should really return true/false. "

(or maybe:)

myObject mustImplement: AnInterface. "This is probably the most commonly used one."

myObject mustBeKindOf: aClass.

myObject mustBeMemberOf: aMember.

(or maybe:)

Declare v: myObject is: SomeClass.

Declare v: myObject implements: SomeInterface.  " Interface adherance is cached in each class."

 

Some of the above methods would need to be heavily optimised, perhaps even be primitives.

 

 

Proxies

 

An Interface could also act as a secure proxy object. It would include a single instvar ("target") and pass all invocations through to its target. It would also include a special method, #disconnect, which will set target to nil.

 

someMethod

    ... code ...

    ^ SomeInterface on: self.

 

 

For efficiency, the interface could be an instance variable in that object.

 

These Proxies / Gates / Cages / Interfaces would usually be passed by some other object such as a facade.

 

 

Example: classes.

 

Currently in Squeak, "anObject class" will return that class. The given class object contains all the methods to edit that class. In SecureSqueak, this must be refactored so that "anObject class" returns a read-only object that does not allow the given class to be edited.

 

(aside: currently "anObject class" is a primitive. This will be changed.)

 

Possibilities:

 

  • Return a proxy instead.
  • Return the class which is read-only, but also provide another object elsewhere with references to the instance variables of class (name, instvars, methoddict, ...) and the ability to edit them. You would then have two classes:  "ReadOnlyClass" and "ClassEditor". This has the disadvantage of not being able to modify the references that the instvars are.
  • Make a special capability object in Squeak. In every method that can edit the class, use "Sender hasCapability: foo" to verify that the sender is allowed to edit that class.
  • Make sure the sender is in a particular Dominion, or in a dominion with a particular capability?
  • Make classes read-only with a "read-only-flag" that prevents setter methods from working once set.

 

 


Page Information

  • 4 months ago [history]
  • View page source
  • You're not logged in
  • No tags yet learn more

Wiki Information

Recent PBwiki Blog Posts