Reference Monitor - Jason Furlong

tunisianbromidrosisInternet and Web Development

Feb 5, 2013 (4 years and 6 months ago)

133 views

Using Aspect
-
Oriented
Software Design to build a
Reference Monitor

Captain Jason Furlong

Department of Electrical & Computer
Engineering

RMC

The Problem with
Software Engineers…

Outline


Background Information


What I built


Findings

Background
Information


Aspect Oriented Software Design
(AOSD)


Scenario Based Access Control (SBAC)


Reference Monitor

Aspect
-
Oriented
Software Design

A new spin on an old idea and

a quick overview of AspectJ

What is AOSD?


Aspect
-
Oriented software
Development (AOSD) aims at
addressing crosscutting concerns by
providing means for their systematic
identification, separation,
representation and composition.


-
Awais Rashid

Cross
-
cutting Concerns


A concern that cuts across the
modularity of a software system.


Symptoms include


Scattering
: Code related to a single
concern is spread across several modules


Tangling
: Code unrelated to the
primary concern of a module is mixed in.


Interface Pollution:
The interface
requirements of several clients are
combined into a single interface.

Cross
-
cutting Concerns

Separated Component

Source: Colyer & Clement
,
Large
-
scale AOSD for Middleware

Proceedings AOSD 2004, Lancaster, UK

Cross
-
cutting Concerns

Homogeneous Cross
-
cutting Concern

Source: Colyer & Clement
,
Large
-
scale AOSD for Middleware

Proceedings AOSD 2004, Lancaster, UK

Cross
-
cutting Concerns

Dedicated Classes

Source: Colyer & Clement
,
Large
-
scale AOSD for Middleware

Proceedings AOSD 2004, Lancaster, UK

Cross
-
cutting Concerns

Source: Colyer & Clement
,
Large
-
scale AOSD for Middleware

Proceedings AOSD 2004, Lancaster, UK

Here be dragons
!

Benefits of AOSD


Increased Comprehensibility


Source code reduction


Better separation of concerns


Decomposition of modules previously considered
monolithic


More adaptable and easier to reuse


Simpler System evolution:


The increased modularity of AOSD systems mean that
fewer modules are affected when another module is
altered.


Programmer specialization through application
transparency


Some concerns, such as security, can be better
implemented

Source: Elrad and Coady

Application Transparency

The act of implementing additional
orthogonal concerns to an oblivious
base functionality through the
successive application of overlapping
modules.

AOSD Technologies


5 Implementations:


Multidimensional Separation of Concerns


Traversal Specifications


Composition Filters


Class Introduction


Join Point Interception

Join Point Interception


A family of languages based on a GPL


AspectJ, AspectWerkz, JBoss
-
AOP (Java)


AspectC++ (C++)


Pythius (Python)


Others based on: Squeak/Smalltalk, XML,
C#/.net, Perl, Ruby, UML…

Join Points

Foo

Bar

public void setx(int a) {..}


Bar.setx(5)


Join Point

Pointcuts


Named collections of Join Points that have
something in common


AspectJ has its own language for describing
pointcuts


Can also describe events in the context of
other pointcuts


Example:


All the calls to the String class


All the calls to a particular
module/package/library that return a Foobar
Object

Advice


This is the base
-
language code that
has been attached to a particular
pointcut or set of pointcuts


3 types:


Before


After


Around

Aspects


Modular entity that consisting of
pointcuts and advice.


This is a module in and of itself that
can have its own attributes and
proprietary methods.


There are also abstract Aspects which
can be inherited from.

Sample Aspect

import business.cheque;

public aspect chequeLogger{


pointcut callChequeSetters(Cheque cheque):



call(public * Cheque.set*(..))&& target(cheque);


before(): callAllSetters(Cheque cheque){



System.out.println(“Calling set method on cheque” +


cheque.toString());}

}//end testAspect




pointcut

advice

wildcards

Class Introduction


Allows the addition of methods,
attributes and interfaces to an existing
class without subclassing or editing
existing code


Violates traditional encapsulation
methods

Compiler Warnings &
Errors


AspectJ pointcuts can be used to generate compiler
errors and warnings


Example:


only ChequeRegistry can access a Cheque Object


pointcut

chequeCalls():


call
(
public

* Cheque.*(..))&&



!
within
(ChequeRegistry);


declare error: chequeCalls():


“Security Error: This is a static method access
violation";

AOSD Conclusion

“Aspect
-
Oriented
Programming…appears to be a
rediscovery of the use of binding
time in creating modular designs.”


-
David M. Weiss


Introduction to the 2001 reprint of Parnas’s
On the Criteria to be Used in
Decomposing Systems into Modules

Scenario
-
Based Access
Control

Scenario Based Access
Control (SBAC)


The Scenario is supposed to mimic the
workflow of an enterprise employee


Based on the observability of Objects


Assumes that the availability of an Object
and the methods that can be invoked will
change according to a scenario hence a
temporal variance in the permission set


In following a Scenario, the model is
deterministic and can satisfy a Safety
Analysis

SBAC uses Objects

Super Secure Software Inc.

15 Enterprise Blvd

Toronto, ON

Make payable to:

Date:

Amount:

Memo:

Signed

Cheque
Number

Signature (Digital)

Payee

Date

Amount

Collaboration

payee :
Customer
drafter :
Employee
1: present bill
theCheque : Cheque
2: draft cheque
theCheque : Cheque
3: verify cheque
4: pass cheque
supervisor :
Employee
Permissions
a. write name of payee
b. write amount
c. write date
d. write Customer #
Permissions
a. read name
b. read amount
c. read date
d. read Customer #
Permissions
a. read name
b. read amount
c. read date
d. read Customer #
e. write Digital Signature
Permissions
a. read name
b. read amount
c. read date
d. read Customer #
Permissions
a. read name
b. read amount
c. read date
d. read Custoumer #
supervisor :
Employee
5: attach Digital Signature
6: pass cheque
cashier :
Employee
8: verify cheque
theCheque : Cheque
9: give money
payee :
Customer
Permissions
a. read name
b. read amount
c. read date
d. read Customer #
7: get Customer identity
payee :
Customer
Permissions
Permissions
Permissions
Permissions
Security Policy
Implementation


Resultant policy is a
set of Message
Sequence Charts


I used both high
-
level
and low
-
level MSCs

supervisor :
SupervisorClass
:
S_ValidityDecision
registry :
ChequeRegistry
getNextChequeData( )
Scenario Ordering: <SEQ>
PARAIN:
supervisor:SupervisorClass
registry:ChequeRegistry

DEFPARA:
<<scenario>>
validityDecision
S_ValidityDecision(DrafterClass, SupervisorClass, ChequeRegistry, ComplexScenario)
getChequeData(int)
NewTask
<<OR>>
CreateCheque
<<SEQ>>
CompareInfo
<<SEQ>>
MailCheque
<<SEQ>>
RejectCheque
<<SEQ>>
ReturnCheque
<<SEQ>>
ValidateCheque
<<SEQ>>
EnvironmentInit
<<SEQ>>
ValidityDecision
<<OR>>
PrintCheques
<<SEQ>>
EditCheque
<<SEQ>>
DrafterTasks
<<OR>>
PrintDecision
<<OR>>
EnvelopeOutput
<<AND>>
GetStamp
<<SEQ>>
GetAddress
<<SEQ>>
PrintCheque
Data
<<SEQ>>
Reference Monitor


Security Abstraction


Originally conceived as a part of a
security kernel and implemented with
a combination of hardware and
software.

Reference Monitor

Subjects

Reference

Monitor

(policy)

Objects

Audit File

Access

Control

Database

Source: Morrie Gasser,
Building a Secure Computer
System, 1988

Reference Monitor


3 Requirements:


Completeness:

It must be impossible to
bypass


Verifiability:

It must be shown to be properly
implemented


Isolation:

It must be tamperproof


What I Did

Building the SBAC Reference
Monitor

The Implementations


Two Implementations on a J2EE
application server.


Can run on Win32 or *NIX.


HTML user interface using Jakarta
-
Struts, an MVC framework.

The Two
Implementations


Cheque example: a set of cooperating
objects working within an EJB.


Built for concurrency of actions


Multiple actors in the scenario


Second example: a SOAP
-
based military HQ
Certificate Authority server


Single Threaded


Closer to a real
-
world Web Services application


Only two actors in the scenario: user and server

Intercepting Methods


Defined pointcuts to intercept method
calls to objects that needed to be
protected according to the security
policy.

Permission Table


Hashtable that contains a collection of
permissions


Each permission hash value based on:


Caller Object instance hash


Receiver object instance hash


Method name


Parameter types


Match permission hash to equivalent join
point hash

Method Matrix


Needed a rigorous methodology for
determining allocation of pointcuts


First example had 8 cooperating
classes = 56 caller/receiver
relationships


Wanted to know what error
declarations could be made

Method Matrix

First Example


Cheque Scenario

Caller
\
Receiver

DrafterClass

SupervisorClass

Cheque

Cheque
Mailing
Machine

Cheque
Registry

ChequeSignature

Envel
ope

StampRepositor
y

DrafterClass









M







SupervisorClass

M





M

M

CM





Cheque

















ChequeMailingMachine









M



C
M

M

ChequeRegistry

M

M


MC







M



ChequeSignature

















Envelope

















StampRepository

















M = Method pointcut

C = Constructor pointcut

Bold

text indicates actor class

Method Matrix (continued)

DrafterClass

Permitted

Supervisor
Class

Permitted

ChequeMailingM
achine

Permitted



createCheque(Ch
equeData)

any

getNextChe
queData()

any

processCheques(
)

any



nextEditCheque()

any

attachSigna
ture(int)

any

addCheque(int)

SupervisorClass

removeNextEdit()

SupervisorCl
ass

rejectClaim(
)

any





editCheque(int)

SupervisorCl
ass

editCheque
ToEdit(int)

any







editUpdate(
ChequeDat
a)

any







addCheque
(int)

ChequeReg
istry







getTasks()



getTasks()



getTasks()



getNextInvoice()



getCheque
Mailer()



getStamper()

addInvoice(OcrDo
cument)







SendChequeToP
ostOffce()

getInvoiceList()







getRegistry()

getSupervisor()









isChequesToEdit(
)









setChequesToEdi
t(boolean)



















public

privileged

aspect

A_ChequeScenarioMonitor {

Scenario upperScenario;

PermissionTable permissionTable;

DrafterClass drafter;

SupervisorClass supervisor;

ChequeMailingMachine mailer;

ChequeRegistry registry;

PrimitiveScenario scenario;


/**


* This ReferenceMonitor has been designed for the ChequeContainerClass environment. If this is


* to be used again in another system then the class that provides the seeds for the scenarios
would


* have to be changed.


* @precondition The container class is of type ChequeContainerClass


*/

public

A_ChequeScenarioMonitor(){}


/**


* This pointcut is used to determine the top
-
level scenario transition


*/

pointcut

startScenario():


execution
(
public

void

ChequeBeanLogic.ejbCreate());

//these are the combined (Inner and Agent)class pointcuts

pointcut

callChequeRegistry():

call
(* ChequeRegistry.*(..)) &&
(
within
(DrafterClass)||
within
(SupervisorClass)||
within
(ChequeMailingMachine));

pointcut

callSupervisorClass():

call
(* SupervisorClass.*(..)) &&
within
(ChequeRegistry);

pointcut

callDrafterClass():

call
(* DrafterClass.*(..)) && (
within
(ChequeRegistry)||
within
(SupervisorClass));

pointcut

callChequeMailingMachine():

call
(* ChequeMailingMachine.*(..)) && (
within
(SupervisorClass));

pointcut

callChequeSignature():

call
(* ChequeSignature.*(..)) &&
within
(SupervisorClass);

pointcut

callEnvelope():

call
(* Envelope.*(..))&&
within
(ChequeMailingMachine);

pointcut

callStampRepository():

call
(* StampRepository.*(..))&&
within
(ChequeMailingMachine);


pointcut

scenarioCallPC(): // group all the call Pointcuts together

callDrafterClass() ||

callSupervisorClass() ||

callChequeRegistry()||

callChequeMailingMachine()||

callChequeSignature()||

callEnvelope()||

callStampRepository();


// Constructor Pointcuts

pointcut

constructorCalls():

call
(
public

ChequeSignature.
new
(business.SupervisorClass)) &&
within
(SupervisorClass)||

call
(
public

Envelope.
new
()) &&
within
(ChequeMailingMachine);


//Agent class pointcuts

pointcut agentDrafterClass():
execution
(
public

int

DrafterClass.createCheque(ChequeData)) ||

execution
(
public

ChequeData DrafterClass.nextEditCheque());

pointcut

agentSupervisorClass():

execution
(
public

ChequeData SupervisorClass.getNextChequeData())||

execution
(
public

void

SupervisorClass.attachSignature(
int
))||

execution
(
public

void

SupervisorClass.rejectClaim())||

execution
(
public

void

editChequeToEdit(
int
))||

execution
(
public

void

editUpdate(ChequeData));

pointcut

agentChequeMailingMachine():

execution
(
public

StringBuffer ChequeMailingMachine.processCheques())||

execution
(
private

StringBuffer ChequeMailingMachine.printCheque(ChequeData, Envelope))||

execution
(
private

void

ChequeMailingMachine.getStamp(ChequeData, Envelope))||

execution
(
private

void

ChequeMailingMachine.getAddress(ChequeData, Envelope));


pointcut

scenarioAgentPC():

agentDrafterClass() || agentSupervisorClass()||agentChequeMailingMachine()||constructorCalls();



/**


*This advice is a supplemental to the constructor to this aspect. It identifies


* the ChequeBeanLogic instance and gets the 3 classes that are needed to


* seed the first scenario:


* The Drafter


* The Supervisor


* The Cheque Mailing Machine


*/


after
() :startScenario(){

JoinPoint jpoint =
thisJoinPoint
;

drafter = ((ChequeBeanLogic)jpoint.getTarget()).getDrafter();

supervisor = ((ChequeBeanLogic)jpoint.getTarget()).getSupervisor();

mailer = ((ChequeBeanLogic)jpoint.getTarget()).getMailer();

registry = ((ChequeBeanLogic)jpoint.getTarget()).getChequeRegistry();


//create a new permissionTable and seed it up with the first scenario.

upperScenario =
new

S_NewTask(drafter, supervisor, registry,
null
);

permissionTable=
new

PermissionTable(upperScenario);

}//end around startScenario and secondary constructor/scenario seeder


before
(): scenarioCallPC() || scenarioAgentPC() {

scenario =permissionTable.permit(
thisJoinPoint
);

if

(scenario ==
null
) {

StringBuffer errorMsg =
new

StringBuffer("permissiondenied");

errorMsg.append(
thisJoinPoint
.toString());

System.out.println("error: " + errorMsg);

throw

new

RuntimeException(errorMsg.toString());

}

}//end before scenario calls()

//set the recently created object to a reference in the scenario that was used.



after
()
returning
(Object object) : constructorCalls() {

if

(scenario !=
null
) {


scenario.setNewObject(object);}

}


//Compiler Errors

pointcut

constructorError():

call
(
public

business.*.
new
(..)) &&

!constructorCalls() && //discard the constructors that are part of scenarios, they're already covered

//these are the exceptions to the rule

!
within
(ejb.*)&& //ejb needs to create seeder classes

!(
call
(
public

Cheque.
new
(..)) &&
within
(ChequeRegistry)) && // only ChequeRegistry can make new Cheque objects

!(
call
(
public

ChequeData.
new
(..)))&& //anybody can create a ChequeData object

!(
call
(
public

ChequeSignature.
new
(..)) &&
within
(Cheque)); // Cheque needs to create a signature


declare

error

: constructorError():

"Security Violation, constructor not permitted";

}//end aspect A_ChequeScenarioMonitor


Code Generated from

the Method Matrix

Reference Monitor Aspect Code

Second Example


Military Certificate Authority Server

public

privileged

aspect

AHQManagerMonitor {


pointcut initializationCalls():



execution(
public

void

HQForm.
new
());



pointcut otherCalls():



execution(
public

SessionContext HQManager.getCtx())||//this is needed by the scenarios



execution(
public

* HQManager.requestCertificate(..))||//container manages the security to this method as it is used by SAAJ



execution(
public

* HQManager.permit(..));//eliminate recursion...



pointcut managerintercept(HQManager manager):



execution(
public

* HQManager.*(..)) &&
this
(manager)&&



!cflow(initializationCalls())&&



!otherCalls();



before(HQManager manager): managerintercept(manager){



Scenario scenario = manager.permit(thisJoinPoint);//check for validity



if

(scenario ==
null
) {//if null, then permission denied


throw exception




StringBuffer errorMsg =
new

StringBuffer("permissiondenied");




errorMsg.append(thisJoinPoint.toString());




System.out.println("error: " + errorMsg);




throw

new

RuntimeException(errorMsg.toString());}}

Findings

Some interesting things I found
along my journey

Benefits of AOSD
-

revisited


Increased Comprehensibility


Better separation of concerns


Decomposition of modules previously considered
monolithic


More adaptable and easier to reuse


Simpler System evolution:


The increased modularity of AOSD systems
mean that fewer modules are affected when
another module is altered.


Programmer specialization through
application transparency and obliviousness

Reference Monitor
Requirements


Completeness
: captures all calls
using wildcards except for initialization
routine.


Isolation
: An attacker would find it
easier to infiltrate the underlying OS
than to compromise the application.


Verifiability
: Uses SBAC, a provably
safe Access Control model.

SBAC


Working dynamic SBAC reference
monitor


SBAC Doesn’t work for everything, like
some J2EE features that require
polymorphism.


Labour intensive


Policy implementation can be fragile


if workflow changes, then the
scenarios have to be rewritten.

Application Transparency


Implementation allowed for pluggable
security at compile time.


2 different build files


Reference monitor framework could be
easily rebuilt to allow for run
-
time
switching.


Business logic was about 99.9%
oblivious of security concern

AOSD


Limitations of AOSD


AspectJ is a static implementation


Slower implementation (about a factor of
4) but the application wasn’t optimized
for speed.


AspectJ was useful for bug tracking
and testing with JUnit.

AOSD
(continued)


Use of Interface Introduction


Used pointcuts and method introduction to
obtain context of some user interface method
calls.

//serverStatus scenario

public

void

HQManager.SserverStatus(){}

public

abstract

void

HQLocal.SserverStatus();

pointcut

SserverStatus(HQServerStatusForm form):

execution
(
public

HashMap HQServerStatusForm.getStatus())&&


this
(form);


before
(HQServerStatusForm form): SserverStatus(form){


form.hqLocal.SserverStatus();

}

Join point limitations


public void setX(int x);

Produces the same join point (and
permission) as:


public void setX(Integer x);


This reduces the obliviousness of the
security implementation.

J2EE


Not the easiest technology/specification to
work with.


Multiple stubs and interfaces made it
difficult to implement SBAC and weave the
reference monitor code.


I was able to use some of the native
security features which saved some time
and effort


Takes a bit of time to set up a J2EE
application server and database

Method Matrix Methodology

Security
Engineer
Programmer
Security Policy

Functional Requirements

Workflow

SBAC

Scenarios

Pointcut Definitions

&

Compiler Errors

uses

creates

uses

uses

creates

supervisor :
SupervisorClass
:
S_ValidityDecision
registry :
ChequeRegistry
getNextChequeData( )
Scenario Ordering: <SEQ>
PARAIN:
supervisor:SupervisorClass
registry:ChequeRegistry

DEFPARA:
<<scenario>>
validityDecision
S_ValidityDecision(DrafterClass, SupervisorClass, ChequeRegistry, ComplexScenario)
getChequeData(int)
Classes

Cheque

Mailer

Supervis
or

Machine

Cheque

M

M

Mailer

CM

M

Machine

M

M

produces

produces

Is checked

against

pointcut

callChequeRegistry():


call
(* ChequeRegistry.*(..)) &&

(
within
(DrafterClass)||

within
(SupervisorClass)||

within
(ChequeMailingMachine));

pointcut

callSupervisorClass():


call
(* SupervisorClass.*(..)) &&

within
(ChequeRegistry);

pointcut

callDrafterClass():


call
(* DrafterClass.*(..)) &&

(
within
(ChequeRegistry)||


within
(SupervisorClass));

pointcut

callChequeMailingMachine():


call
(* ChequeMailingMachine.*(..)) &&

(
within
(SupervisorClass));

pointcut

callChequeSignature():


call
(* ChequeSignature.*(..)) &&

within
(SupervisorClass);

pointcut

callEnvelope():


call
(* Envelope.*(..)) &&

within
(ChequeMailingMachine);

pointcut

callStampRepository():


call
(* StampRepository.*(..)) &&

within
(ChequeMailingMachine);

Method

Matrix

Future Work


Use a dynamic AOSD technology such as
AspectWerkz or JBoss
-
AOP


Clean up some of the pointcuts


Integrate with the J2EE server software


Automate generation of scenarios from
Rational Rose (or other UML/MSC tool)


Refine the SBAC framework


Performance


Make the framework more opaque


Implementation in a COTS environment
where components aren’t fully trusted


Summary


AOSD modularizes cross
-
cutting
concerns


Created Reference monitor using
AspectJ that was completely modular


Dynamic Implementation of SBAC
using AOSD and AspectJ


Questions

?

Class Introduction in
AspectJ

Given:


public class Cheque{



private int value;}


…and in another module…


public aspect ModifiedCheque{



public int Cheque.getValue(){




return value;}


}

Motivational Quote

“people tend to equate the
reference
monitor

concept with the security
kernel approach… You should try to
keep an open mind, however and be
willing to accept the possibility that
other types of
reference monitors

may someday exist.”

Morrie Gasser,
Building a

Secure Computer System, 1988