From: bufie
Subject: trace/untrace question
Date: 
Message-ID: <Fn9pc.49903$iF6.4507996@attbi_s02>
Hello,

Please pardon my ignorance if this is common knowledge, but I haven't been
able to find the answer to this question.

I'm developing an add-on module for an application with a lisp extension
language.  I have a lisp function that calls several other functions (such
as security/license checking) that are part of the API for the application..
For security reasons, I want to prevent tracing of those function calls.  (I
will be distributing only compiled code).  I know I can do something like
this:

(defun myfunction ()
  (let ((tracing)
         (trace-output *trace-output*)
         (okay)
          )
    (setq *trace-output* nil)
    (dolist (f trace)
      (when (equalp "SECURITY-CHECK-FUNCTION" f)
           (setq tracing t)
           (untrace security-check-function)
         ))
    (setq okay (security-check-function myargs))
    (when tracing
      (trace security-check-function)
    (setq *trace-output* trace-output)
   ... ;; rest of function goes here
  )

So my question is this:  is there any way for someone to break this method
and get access to the security-check-function parameters?  I don't know if
there is a way to change the value of *trace-output* or to re-enable the
trace function in the middle of the above function.  I'm thinking that it
should be secure, but I'm also paranoid about security for this application.

Any thoughts?

Thank you!

bufie

From: Edi Weitz
Subject: Re: trace/untrace question
Date: 
Message-ID: <m3y8nupxzg.fsf@bird.agharta.de>
On Fri, 14 May 2004 19:47:49 GMT, "bufie" <·····@spamneggs.com> wrote:

> I'm developing an add-on module for an application with a lisp
> extension language.

Is this "a lisp language" or is it Common Lisp? From your example
below it could be Common Lisp but I'm not sure.

> I have a lisp function that calls several other functions (such as
> security/license checking) that are part of the API for the
> application..  For security reasons, I want to prevent tracing of
> those function calls.  (I will be distributing only compiled code).
> I know I can do something like this:
>
> (defun myfunction ()
>   (let ((tracing)
>          (trace-output *trace-output*)
>          (okay)
>           )
>     (setq *trace-output* nil)
>     (dolist (f trace)
>       (when (equalp "SECURITY-CHECK-FUNCTION" f)
>            (setq tracing t)
>            (untrace security-check-function)
>          ))
>     (setq okay (security-check-function myargs))
>     (when tracing
>       (trace security-check-function)
>     (setq *trace-output* trace-output)
>    ... ;; rest of function goes here
>   )

Some comments about your code (assuming this is Common Lisp):

*TRACE-OUTPUT* is a special variable. You don't have to do something
like

  (let ((trace-output *trace-output*))
    (setq *trace-output* nil)
    (do-something)
    (setq *trace-output* trace-output))

The same can be achieved more elegantly like this:

  (let ((*trace-output* nil))
    (do-something))

Also, you shouldn't bind *TRACE-OUTPUT* to NIL because NIL is not an
output stream. If you want to send the output to /dev/null (so to say)
then the common idiom is to use (MAKE-BROADCAST-STREAM). (Like that,
i.e. with no arguments.)

Instead of

  (dolist (f trace)
    (foo))

you most likely mean

  (dolist (f (trace))
    (foo))

However, you can't be sure that your EQUALP test will return true if
your security function is amongst the functions currently traced
(assuming that by "SECURITY-CHECK-FUNCTION" you don't mean a string
but the function itself). It /might/ be the case in your
implementation but that's not required by the ANSI standard.

/If/ you're able to find the function you're looking for with EQUALP
then you'll also find it with EQ. You can rewrite the DOLIST part to
look like this:

  (when (member #'security-function (trace) :test #'eq)
    (setq tracing t)
    (untrace security-function))

> So my question is this: is there any way for someone to break this
> method and get access to the security-check-function parameters?  I
> don't know if there is a way to change the value of *trace-output*
> or to re-enable the trace function in the middle of the above
> function.  I'm thinking that it should be secure, but I'm also
> paranoid about security for this application.
>
> Any thoughts?

I think this is implementation-dependent. You should ask the vendor of
the Lisp you're using.

Cheers,
Edi.
From: bufie
Subject: Re: trace/untrace question
Date: 
Message-ID: <Arapc.49102$536.8424257@attbi_s03>
Hi Edi!

Thanks for the reply!

> > I'm developing an add-on module for an application with a lisp
> > extension language.
>
> Is this "a lisp language" or is it Common Lisp? From your example
> below it could be Common Lisp but I'm not sure.

I'm quite certain it uses the KCL core, so it would be common lisp

> > I have a lisp function that calls several other functions (such as
> > security/license checking) that are part of the API for the
> > application..  For security reasons, I want to prevent tracing of
> > those function calls.  (I will be distributing only compiled code).
> > I know I can do something like this:

[original code snipped]

> Some comments about your code (assuming this is Common Lisp):
>
> *TRACE-OUTPUT* is a special variable. You don't have to do something
> like
>
>   (let ((trace-output *trace-output*))
>     (setq *trace-output* nil)
>     (do-something)
>     (setq *trace-output* trace-output))
>
> The same can be achieved more elegantly like this:
>
>   (let ((*trace-output* nil))
>     (do-something))

Thanks!  I didn't realize this -- very helpful!

> Also, you shouldn't bind *TRACE-OUTPUT* to NIL because NIL is not an
> output stream. If you want to send the output to /dev/null (so to say)
> then the common idiom is to use (MAKE-BROADCAST-STREAM). (Like that,
> i.e. with no arguments.)

Again, thank you!  I thought that nil wasn't right, but I didn't know about
(make-broadcast-stream).

> Instead of
>
>   (dolist (f trace)
>     (foo))
>
> you most likely mean
>
>   (dolist (f (trace))
>     (foo))

Yes, you are correct -- I just re-typed everything for this and forgot the
() on trace...

> However, you can't be sure that your EQUALP test will return true if
> your security function is amongst the functions currently traced
> (assuming that by "SECURITY-CHECK-FUNCTION" you don't mean a string
> but the function itself). It /might/ be the case in your
> implementation but that's not required by the ANSI standard.

Actually I was typing from memory before -- I actually use string-equal for
this, though I will look at the "member" function below -- that's a much
nicer way to do it!

> /If/ you're able to find the function you're looking for with EQUALP
> then you'll also find it with EQ. You can rewrite the DOLIST part to
> look like this:
>
>   (when (member #'security-function (trace) :test #'eq)
>     (setq tracing t)
>     (untrace security-function))

So another question -- if I set *trace-output* to (make-broadcast-stream),
is there any reason to untrace/retrace the function?  Is there any other
side effect that can be done from the (trace somefunction) that will output
the results of the trace to somewhere other than specified by *trace-output*
?  Sorry to be paranoid, but want to be safe!

Thanks again for your feedback!  I really appreciate it!

bufie
From: Edi Weitz
Subject: Re: trace/untrace question
Date: 
Message-ID: <m3brkq36p0.fsf@ella.agharta.de>
On Fri, 14 May 2004 21:00:16 GMT, "bufie" <·····@spamneggs.com> wrote:

> I'm quite certain it uses the KCL core, so it would be common lisp

Hmmm. AFAIK (someone correct me if I'm wrong) KCL is a) not maintained
any more, and b) not an ANSI Common Lisp - it's based on CLtL2 or even
CLtL1. This implies that some of things I said earlier might or might
not apply to KCL. You'll have to check yourself.

> So another question -- if I set *trace-output* to
> (make-broadcast-stream), is there any reason to untrace/retrace the
> function?  Is there any other side effect that can be done from the
> (trace somefunction) that will output the results of the trace to
> somewhere other than specified by *trace-output* ?  Sorry to be
> paranoid, but want to be safe!

I /think/ you should be safe if you just rebind
*TRACE-OUTPUT*. However, as I said, there might be
implementation-dependent tricks to get at the data you want to hide. I
suppose only the KCL developers can really answer your questions... :(

Cheers,
Edi.
From: Thomas A. Russ
Subject: Re: trace/untrace question
Date: 
Message-ID: <ymi1xlislkh.fsf@sevak.isi.edu>
Well, if you're really that paranoid, what is to stop someone from just
establishing a breakpoint on your security function using a debugger?
In fact, there are a number of Lisp systems which allow you to set just
such breakpoints using the TRACE form.  Of course, if they can get to
the debugger, they can also usually return any value they want from the
function.  So regardless of the arguments, they could "pass" the
security check just by returning T instead.

Also, if your Lisp system has a DEFADVICE function, then they can just
advise the security check function.

It would probably be better to implement your security check function in
such a way that looking at the input arguments doesn't compromise the
security of the system.  You probably would want to use local (FLET or
LABELS) functions for the implementation.

-- 
Thomas A. Russ,  USC/Information Sciences Institute
From: John Thingstad
Subject: Re: trace/untrace question
Date: 
Message-ID: <opr76x0ut8pqzri1@mjolner.upc.no>
check out ignore-errors handler-bind etc
It is time to read up un lisp's exception handeling.

On 17 May 2004 16:03:42 -0700, Thomas A. Russ <···@sevak.isi.edu> wrote:

>
> Well, if you're really that paranoid, what is to stop someone from just
> establishing a breakpoint on your security function using a debugger?
> In fact, there are a number of Lisp systems which allow you to set just
> such breakpoints using the TRACE form.  Of course, if they can get to
> the debugger, they can also usually return any value they want from the
> function.  So regardless of the arguments, they could "pass" the
> security check just by returning T instead.
>
> Also, if your Lisp system has a DEFADVICE function, then they can just
> advise the security check function.
>
> It would probably be better to implement your security check function in
> such a way that looking at the input arguments doesn't compromise the
> security of the system.  You probably would want to use local (FLET or
> LABELS) functions for the implementation.
>



-- 
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/