[OWASP-ESAPI] AccessController context

Jim Manico jim at manico.net
Wed Jul 30 15:08:20 EDT 2008


 > I think a class and a Long won't be sufficient for all cases to 
identify the entire context.  (this also assumes all keys are Longs 
which may not always be true)

I agree 100%, I'm back to Object or the interface method. But, we can 
always cast up to long, but not the other way around. Big sites like 
myspace use longs as identity - although for enterprise apps int should 
be fine. But that doesn't matter - I agree that class/long will not work 
well.

So, back to your example.

Why not solve

 >  setTarget(thisAccount).setContext("amount", 
theAmountToTransfer).isAuthorized("transfer") (adding as many set's as 
needed)

As follows:

First of all, you would never just call:

public void transfer(final Long amount)

without context.

So lets assume that the transfer is wrapped in a Transfer object that 
contains details like time/currency/and the account involved. In that 
case, you could just call:

*public boolean isAuthorized(String function, TransferTransaction 
transaction) {

       if (function.equals("executeTransfer")) {

           Account sourceAccount = transaction.getSourceAccount();
           Account targetAccount = transaction.getTargetAccount();
           long amount = transaction.getAmount();
           int userId = getUserIdFromESAPI();
   
          //if the amount is over 5000 return false
          //if user does not own both account return false
          //if amount does not exist in source account return false
          //if another transaction is pending return false
          //if its snowing in honolulu return false
          //then lock and return true
        }

        throw RuntimeFunctionNotSupported();
}*

(or have a TransferTransaction object with a isAuthorized(String 
function) interface....)

In my subjective/opinionated world - the chaining looks hard to read 
(and therefor hard to maintain or audit), the map will lead to 
performance problems,


> Jim,
>   Thanks for the info.  Just a quick brain dump...
>
> I think a class and a Long won't be sufficient for all cases to 
> identify the entire context.  (this also assumes all keys are Longs 
> which may not always be true)
>
> I agree that my example might look too long, but it's as long as it 
> needs to be to get all the information into the isAuthorized (if you 
> need no additional information, then it is exactly like it was before).
>
> As far as why not call:
> ESAPI.getAccessController().
> isAuthorized(thisAccount, "delete"),
> I probably did not give a very good example.
> Let me try again with our wonderful bank app and transfering.
> The operation/function is transfer, but we will also need the amount 
> to transfer (not stored in the account yet, so we can not get it from 
> the account) as well as the account (for more complicated scenarios, 
> we might need more information than just one extra object).
> so isAuthorized("transfer", thisAccount), is not sufficient (missing 
> the amount that the user is attempting to transfer.  The limit on who 
> can transfer how much is in the implementation, but the amount 
> attempting to be transfered must be passed into the Authenticator),
>
> So I see several options here (there are probably more, but this is 
> what I saw right off):
>
> 1) Chaining
>  setTarget(thisAccount).setContext("amount", 
> theAmountToTransfer).isAuthorized("transfer") (adding as many set's as 
> needed)
>
> 2) A Map-like object (Similar to what Jeff was suggesting):
>   MapLikeThing context;
>   context.set("account",thisAccount)
>   context.set("amount", amountToTransfer);
>   isAuthorized("transfer",context); // the isAuthorized could also 
> take an arbitrary object here as well as the map
>
>
> 3) A callback object (can be null);
>   So we might have an interface which is as compilcated as needed 
> called AuthorizationCallbacks with methods like getContext, getTarget, 
> getXXX.  This most likely will be anonymous inline instances...
>   so the isAuthorized method can be overloaded to take either nothing 
> or a Callback object;
>
> So my isAuthorized implementation might look like this:
>   isAuthorized(String function, Callbacks callbacks) {
>     Long amount = callbacks.getContext("amount");
>     Object target = callbacks.getTarget();
>     // do some really complex logic here.
>   }
>
>
> And the client might look like this...  (this is ugly and complex)
> public void transfer(final Long amount) {
>         if (isAuthorized("transfer",
>                 new CallbackInterface() {
>                   public Object getContext(String key) {
>                       if ("amount".equals(key)) {
>                         return amount;
>                       }
>                       return null;
>                   }
>                   public Object getTarget() {
>                       return this;
>                   }
>                 })
>         ) {
>             return AUTHORIZTION_ERROR;
>         }
> // do the transfer
> }
>
> Each of these 3 ways has it's advantages and disadvantages, but they 
> all allow for arbitray information to be sent into the authorization 
> engine without any preconcieved notions about how many pieces of 
> information or what type the information will be needed.
>
> -Kevin
>
>
>
> On Wed, Jul 30, 2008 at 12:09 PM, Jim Manico <jim at manico.net 
> <mailto:jim at manico.net>> wrote:
>
>     -----BEGIN PGP SIGNED MESSAGE-----
>     Hash: SHA1
>      
>     Nice Kevin, good stuff.
>
>
>     | I'm not really sure exactly what you meant by the method
>     |  isAuthorized(String function, Class entityType, Long identifier)
>     *
>     **I'm splitting out "Object" into "Class" and "Identity" - So in
>     your world, we would call:*
>
>     isAuthorized("execute", SavingsTransaction.class, 3321l)
>
>     *But I don't like this class method - we would have to re-load the
>     object. I'd rather see*
>
>     |  isAuthorized(String function, Object entityType)
>     or
>     | isAuthorized(String function)
>     *at the object level (see the interface example below, which is
>     essentially the same thing as isAuthorized(String function, Object
>     entityType)**
>     *
>     *Looking at:*
>
>
>     ESAPI.getAccessController().setContext("amount",someValue).setOperation("delete").setTarget(thisAccount).isAuthorized("someFunction");
>
>     *It looks a little complex... why not call:*
>
>     ESAPI.getAccessController().isAuthorized(thisAccount, "delete")
>
>     *and push the rule with amount into the function?*
>
>     *- Jim***
>
>     | Jeff,
>     | Very nice write-up of general requirements.  I think you nailed it.
>     |
>     | Jim,
>     | I'm not really sure exactly what you meant by the method
>     | *isAuthorized(String function, Class entityType, Long identifier)
>     | *Can you please elaborate.
>     |
>     | If I am following you, the AccessController interface could have
>     several methods added to take care of the issues Jeff listed above.
>     | Let's pretend setTarget, setOperation and setContext are added
>     to the interface (to take care of a few things that Jeff listed). 
>     (PS, I'm a big fan of these methods returning "this", to make
>     chaining possible.)
>     |
>     | So my code could look like it does now, if I don't want any
>     added functionality.
>     | ESAPI.getAccessController().isAuthorized("someFunction");
>     |
>     | But If I need the functionality, my code could look like this:
>     | ESAPI.getAccessController().setContext("amount",
>     someValue).setOperation("delete").setTarget(thisAccount).isAuthorized("someFunction");
>     |
>     | Does that make sense?  Access implementations that do not care
>     about context or other things could write do nothing methods (or
>     inherit from a skeleton class).
>     |
>     | At least, this is how I see still getting down to the single
>     isAuthorized call the Jim is suggesting.
>     |
>     |
>     | Some down sides of this that I see are:
>     | 1) Probably not thread safe if the ESAPI.getAccessController is
>     done as a singleton as it currently is.
>     | 2) The access controller could now be holding onto a large
>     amount of data (Unintended object referenes)
>     |
>     | -Kevin
>     |
>     |
>     |
>     |
>
>
> ------------------------------------------------------------------------
>
> _______________________________________________
> OWASP-ESAPI mailing list
> OWASP-ESAPI at lists.owasp.org
> https://lists.owasp.org/mailman/listinfo/owasp-esapi
>   


-- 
Jim Manico, Senior Application Security Engineer
jim.manico at aspectsecurity.com | jim at manico.net
(301) 604-4882 (work)
(808) 652-3805 (cell)

Aspect Security™
Securing your applications at the source
http://www.aspectsecurity.com

---------------------------------------------------------------
Management, Developers, Security Professionals ...
... can only result in one thing. BETTER SECURITY.
http://www.owasp.org/index.php/OWASP_NYC_AppSec_2008_Conference  
Sept 22nd-25th 2008


-------------- next part --------------
An HTML attachment was scrubbed...
URL: https://lists.owasp.org/pipermail/owasp-esapi/attachments/20080730/35754eb6/attachment-0001.html 


More information about the OWASP-ESAPI mailing list