[racket] Limiting net-repl provided functions
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!