[racket] Limiting net-repl provided functions

From: Jukka Tuominen (jukka.tuominen at finndesign.fi)
Date: Tue Jun 28 04:07:20 EDT 2011

Thanks Eli, much appreciated!

By means of just limiting provided functions, the latter approach seems
bullet-proof (although lacking sandbox characteristics that net-repl partly
does already AFAIU).

If however, I would choose the sandbox approach, can you think of any way to
break into the system by utilizing some 'invisible' features? Is this also
bullet-proof?

br, jukka


> -----Original Message-----
> From: Eli Barzilay [mailto:eli at barzilay.org]
> Sent: 28 June 2011 10:33
> To: Jukka Tuominen
> Cc: Sam Tobin-Hochstadt; users at racket-lang.org
> Subject: RE: [racket] Limiting net-repl provided functions
>
>
> 10 minutes ago, Jukka Tuominen wrote:
> >
> > > -----Original Message-----
> > > From: Eli Barzilay [mailto:eli at barzilay.org]
> > > Sent: 28 June 2011 09:45
> > > To: Jukka Tuominen
> > > Cc: Sam Tobin-Hochstadt; users at racket-lang.org
> > > Subject: RE: [racket] Limiting net-repl provided functions
> > >
> > >
> > > About a minute ago, Jukka Tuominen wrote:
> > > >
> > > > > The sandbox is working in an isolated world (by design, of
> > > > > course), so you need to do the (require "sb-functions.rkt") inside
> > > > > the sandbox.  For example, just use (sb-eval '(require ...)).
> > > >
> > > > Wouldn't that mean that the sb-evaluator has to be first initiated
> > > > to understand 'require' plus many other primitives, not just the
> > > > intented f1, f2, f3?
> > >
> > > Yes.
> > >
> > >
> > > > Is this even possible?
> > >
> > > Yes.  You can get that with
> > >
> > >   (make-evaluator 'racket/base)
> >
> > Sorry, I meant to say that is it possible to have only the f1,
> f2, and f3
> > provided, but not even 'require'...
> > >
> > > If you want a limited language, then you can make up a language with
> > > `require' and the limited set of bindings you want in.  If you also
> > > don't want `require' in the language, you can make the language itself
> > > provide the functions that you want to make public, but not `require'
> > > itself.  Yet another option is to use `call-in-sandbox-context' with
> > > `namespace-require'.
> >
> > yes, I want to have a more limited language, yet without leaving the
> > comfort of Racket, meaning that on the server side you have all the
> > familiar tools to create new 'primitives', and on the client side,
> > use these primitives just like any other, no matter how and where
> > they take place.
>
> So that's what you need to do.  Here's an example:
>
>   ---- limited.rkt ---
>   #lang racket/base
>   (provide
>    ;; special things
>    #%app #%module-begin #%datum #%top #%top-interaction
>    ;; visible primitives
>    + - quote length
>    ;; additional functions
>    f1)
>   ;; definitions for the additional functions
>   (define (f1 l) (length l))
>
> and then:
>
>   > (require racket/sandbox)
>   > (define e (make-evaluator "limited.rkt"))
>   > (e '(+ 1 2))
>   3
>   > (e '(- (f1 '(x y z)) 1))
>   2
>
> and not much else works...  Specifically, `require' is not there:
>
>   > (e '(require racket))
>   reference to an identifier before its definition: require in module:
>   "program"
>
>
> > > (All of this is much more complicated then what Matthias
> > > originally hinted at: if you know the set of functions that you
> > > want to expose, then you can just dispatch on the input symbols
> > > and call the corresponding function.)
> >
> > I wish I was just pretending not to see the obvious (sigh)...  Yes
> > please, I would very much like the obvious and simple solution! :)
> > Not just for me, but also for the ones that hopefully will end up
> > creating these new services eventually. Even the hint 2 isn't enough
> > for me unfortunately (sigh 2)...
>
> Just something like this:
>
>   (require "server-functions.rkt")
>   (define request (read from-client))
>   (unless (and (list? request) (pair? request) (symbol? (car request)))
>           ;; or use `match' instead
>     (throw-error-to-port to-client "bad request"))
>   (apply (case (car request)
>            [(f1) f1]
>            [(f2) f2]
>            ... more here ...)
>          (cdr request))
>
> --
>           ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
>                     http://barzilay.org/                   Maze is Life!



Posted on the users mailing list.