[racket-users] Questions about module encapsulation guarantees

2018-09-09 Thread Jack Firth
If I make a symbol with `gensym` (or do anything else that creates a new 
value that's not `eq?` to any other value) in some module, what are the 
absolute upper limits on my ability to use that symbol within the module 
without allowing any other modules to get ahold of the symbol? What do code 
inspectors, namespaces, sandboxes, eval, `unsafe` APIs, the FFI, etc. make 
possible for malicious code in external modules?

Context: I'm exploring a "contract witness" idea whose implementation 
currently relies on the eq?-ness of opaque struct instances for security. 
But I vaguely recall hearing once that the The Only Way To Be Sure when it 
comes to struct encapsulation is to put the definition of a struct inside a 
lambda, otherwise some sort of nebulous "bad things" are possible in 
external code that wants to break the invariants of  a struct type.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Questions about module encapsulation guarantees

2018-09-12 Thread Matthew Flatt
At Sun, 9 Sep 2018 18:52:57 -0700 (PDT), Jack Firth wrote:
> If I make a symbol with `gensym` (or do anything else that creates a new 
> value that's not `eq?` to any other value) in some module, what are the 
> absolute upper limits on my ability to use that symbol within the module 
> without allowing any other modules to get ahold of the symbol? What do code 
> inspectors, namespaces, sandboxes, eval, `unsafe` APIs, the FFI, etc. make 
> possible for malicious code in external modules?

If you don't change the code inspector, than a third party can get into
the module body's namespace. So, if you bind the gensym with a
definition, that will be easy to see.

If you retain the symbol only through a closure, as cwebber shows, then
getting to the gensym is trickier, but it's still possible via unsafe
APIs. Setting the code inspector should prevent access to unsafe APIs
or anything else that can inspect arbitrary data --- modulo bugs in the
runtime system, of course, but also any bugs in a module that might
make use of unsafe features and get loaded before the code inspector is
changed.

> Context: I'm exploring a "contract witness" idea whose implementation 
> currently relies on the eq?-ness of opaque struct instances for security. 
> But I vaguely recall hearing once that the The Only Way To Be Sure when it 
> comes to struct encapsulation is to put the definition of a struct inside a 
> lambda, otherwise some sort of nebulous "bad things" are possible in 
> external code that wants to break the invariants of  a struct type.

The only difference between being under a `lambda` and not should be
whether the relevant module or top-level namespace is accessible to the
code that you don't trust. Changing the code inspector disables
`module->namespace`.

Meanwhile, access to the struct content otherwise would need a more
powerful inspector (i.e., you don't have to change the inspector, but
merely refrain from changing it to an ancestor of the one used to
create the structure type).

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Sealers/unsealers in Racket (Re: [racket-users] Questions about module encapsulation guarantees)

2018-09-10 Thread Christopher Lemmer Webber
Jack Firth writes:

> If I make a symbol with `gensym` (or do anything else that creates a new
> value that's not `eq?` to any other value) in some module, what are the
> absolute upper limits on my ability to use that symbol within the module
> without allowing any other modules to get ahold of the symbol? What do code
> inspectors, namespaces, sandboxes, eval, `unsafe` APIs, the FFI, etc. make
> possible for malicious code in external modules?
>
> Context: I'm exploring a "contract witness" idea whose implementation
> currently relies on the eq?-ness of opaque struct instances for security.
> But I vaguely recall hearing once that the The Only Way To Be Sure when it
> comes to struct encapsulation is to put the definition of a struct inside a
> lambda, otherwise some sort of nebulous "bad things" are possible in
> external code that wants to break the invariants of  a struct type.

Struct inside a function is certainly a way to do it.  You may be
interested in the idea of sealer/unsealer pairs from the object
capability world.  I borrowed the implementation of this from Jonathan
Rees' W7 code.  Consider this waived into the public domain, under CC0,
but also with any potential patents waived under the same terms.

Imagine the ability to make a magical canning kit and a can opener,
where the cans produced can only be opened by the respective can opener.

  ; Create a new sealer / unsealer pair and sealed? predicate
  ; sealer-name is optional and just for debugging help
  (define (new-seal [sealer-name #f])
(define struct-name
  (if sealer-name
  (string->symbol (string-append "sealed-by-" (symbol->string 
sealer-name)))
  'sealed))
(define-values (struct:seal seal sealed? seal-ref seal-set!)
  (make-struct-type struct-name #f 1 0))
(define unseal
  (make-struct-field-accessor seal-ref 0))
(values seal unseal sealed?))

Now let's try using it:

  (define-values (can-sealer can-unseal can-seal?)
(new-seal 'canning-factory))

The traditional ocap example is to seal tuna, but I'm vegetarian.

  (define lunch (seal "chickpea salad"))

  lunch ; #

I'm in control of the sealer from my little canning factory, I don't
give it to anyone else.  Only someone with the matching unsealer can
open this can.  I can safely put it in the fridge.

I can make sure this can is my lunch, in case I forgot:

  (can-sealed? lunch) ; #t

And I can get to its contents:

  (can-unseal lunch) ; "chickpea salad"

Not that this looks a lot like decryption, but with lexical scope only.
It's possible I am okay with someone else opening my objects, in which
case I might give them the can-sealed? predicate and the can-unseal
procedure... then they can open it, but be sure it's from me.  And
with that you can more or less implement signatures.

BTW, you can do powerful stuff with this... here's an example where
you implement digital money:

  http://erights.org/elib/capability/ode/ode-capabilities.html

Here's the same example from that article, written in Racket code:

  (define (make-mint name)
(define-values (sealer unsealer sealed?)
  (new-seal name))
(define/contract mint%
  (class/c [make-purse (->m nonnegative-integer? any/c)])
  (class* object% (writable<%>)
(super-new)
(define/public (custom-display p)
  (display (format "#<~a mint>" name) p))
(define/public (custom-write p)
  (custom-display p))

(define this-mint this)
(define/public (make-purse balance)
  (define/contract (decr amount)
(-> (and/c (>=/c 0)
   (lambda (amt)
 (<= amt balance)))
void?)
(set! balance (- balance amount)))
  (define/contract purse%
(class/c [get-balance (->m integer?)]
 [deposit (->m integer? any/c void?)])
(class* object% (writable<%>)
  (super-new)
  
  (define/public (custom-display p)
(display (format "#" balance name) p))
  (define/public (custom-write p)
(custom-display p))

  (define/public (get-balance)
balance)
  (define/public (sprout)
(send this-mint make-purse 0))
  (define/public (get-decr)
(sealer decr))

  (define/public (deposit amount src)
((unsealer (send src get-decr)) amount)
(set! balance (+ balance amount))
(void
  (new purse%
(new mint%))

  (module+ test
(define carol-mint
  (make-mint 'Carol))
(define alice-main-purse
  (send carol-mint make-purse 1000))

(define bob
  (new
   (class object%
 (super-new)
 (define bob-main-purse
   (send carol-mint make-purse 0))
 (define/public (go-on-ride payment)
   (send bob-main-purse deposit 10 payment)
   (displayln "Whee!

Re: Sealers/unsealers in Racket (Re: [racket-users] Questions about module encapsulation guarantees)

2018-09-10 Thread Matthias Felleisen





> On Sep 10, 2018, at 10:09 AM, Christopher Lemmer Webber 
>  wrote:
> 
> Jack Firth writes:
> 
>> If I make a symbol with `gensym` (or do anything else that creates a new
>> value that's not `eq?` to any other value) in some module, what are the
>> absolute upper limits on my ability to use that symbol within the module
>> without allowing any other modules to get ahold of the symbol? What do code
>> inspectors, namespaces, sandboxes, eval, `unsafe` APIs, the FFI, etc. make
>> possible for malicious code in external modules?
>> 
>> Context: I'm exploring a "contract witness" idea whose implementation
>> currently relies on the eq?-ness of opaque struct instances for security.
>> But I vaguely recall hearing once that the The Only Way To Be Sure when it
>> comes to struct encapsulation is to put the definition of a struct inside a
>> lambda, otherwise some sort of nebulous "bad things" are possible in
>> external code that wants to break the invariants of  a struct type.
> 
> Struct inside a function is certainly a way to do it.  You may be
> interested in the idea of sealer/unsealer pairs from the object
> capability world.  I borrowed the implementation of this from Jonathan
> Rees' W7 code.  Consider this waived into the public domain, under CC0,
> but also with any potential patents waived under the same terms.
> 

Does this really differ from Jim Morris’s sealing? 

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Sealers/unsealers in Racket (Re: [racket-users] Questions about module encapsulation guarantees)

2018-09-10 Thread David Storrs
This is a very cool thing, but may I suggest choosing a different name than
'can'?  '(can-unseal lunch)' reads less like a verb and more like a
predicate where someone forgot the '?' -- "Are you able to unseal lunch?"
as opposed to "Unseal my lunch now".

On Mon, Sep 10, 2018 at 11:09 AM, Christopher Lemmer Webber <
cweb...@dustycloud.org> wrote:

> Jack Firth writes:
>
> > If I make a symbol with `gensym` (or do anything else that creates a new
> > value that's not `eq?` to any other value) in some module, what are the
> > absolute upper limits on my ability to use that symbol within the module
> > without allowing any other modules to get ahold of the symbol? What do
> code
> > inspectors, namespaces, sandboxes, eval, `unsafe` APIs, the FFI, etc.
> make
> > possible for malicious code in external modules?
> >
> > Context: I'm exploring a "contract witness" idea whose implementation
> > currently relies on the eq?-ness of opaque struct instances for security.
> > But I vaguely recall hearing once that the The Only Way To Be Sure when
> it
> > comes to struct encapsulation is to put the definition of a struct
> inside a
> > lambda, otherwise some sort of nebulous "bad things" are possible in
> > external code that wants to break the invariants of  a struct type.
>
> Struct inside a function is certainly a way to do it.  You may be
> interested in the idea of sealer/unsealer pairs from the object
> capability world.  I borrowed the implementation of this from Jonathan
> Rees' W7 code.  Consider this waived into the public domain, under CC0,
> but also with any potential patents waived under the same terms.
>
> Imagine the ability to make a magical canning kit and a can opener,
> where the cans produced can only be opened by the respective can opener.
>
>   ; Create a new sealer / unsealer pair and sealed? predicate
>   ; sealer-name is optional and just for debugging help
>   (define (new-seal [sealer-name #f])
> (define struct-name
>   (if sealer-name
>   (string->symbol (string-append "sealed-by-" (symbol->string
> sealer-name)))
>   'sealed))
> (define-values (struct:seal seal sealed? seal-ref seal-set!)
>   (make-struct-type struct-name #f 1 0))
> (define unseal
>   (make-struct-field-accessor seal-ref 0))
> (values seal unseal sealed?))
>
> Now let's try using it:
>
>   (define-values (can-sealer can-unseal can-seal?)
> (new-seal 'canning-factory))
>
> The traditional ocap example is to seal tuna, but I'm vegetarian.
>
>   (define lunch (seal "chickpea salad"))
>
>   lunch ; #
>
> I'm in control of the sealer from my little canning factory, I don't
> give it to anyone else.  Only someone with the matching unsealer can
> open this can.  I can safely put it in the fridge.
>
> I can make sure this can is my lunch, in case I forgot:
>
>   (can-sealed? lunch) ; #t
>
> And I can get to its contents:
>
>   (can-unseal lunch) ; "chickpea salad"
>
> Not that this looks a lot like decryption, but with lexical scope only.
> It's possible I am okay with someone else opening my objects, in which
> case I might give them the can-sealed? predicate and the can-unseal
> procedure... then they can open it, but be sure it's from me.  And
> with that you can more or less implement signatures.
>
> BTW, you can do powerful stuff with this... here's an example where
> you implement digital money:
>
>   http://erights.org/elib/capability/ode/ode-capabilities.html
>
> Here's the same example from that article, written in Racket code:
>
>   (define (make-mint name)
> (define-values (sealer unsealer sealed?)
>   (new-seal name))
> (define/contract mint%
>   (class/c [make-purse (->m nonnegative-integer? any/c)])
>   (class* object% (writable<%>)
> (super-new)
> (define/public (custom-display p)
>   (display (format "#<~a mint>" name) p))
> (define/public (custom-write p)
>   (custom-display p))
>
> (define this-mint this)
> (define/public (make-purse balance)
>   (define/contract (decr amount)
> (-> (and/c (>=/c 0)
>(lambda (amt)
>  (<= amt balance)))
> void?)
> (set! balance (- balance amount)))
>   (define/contract purse%
> (class/c [get-balance (->m integer?)]
>  [deposit (->m integer? any/c void?)])
> (class* object% (writable<%>)
>   (super-new)
>
>   (define/public (custom-display p)
> (display (format "#" balance name) p))
>   (define/public (custom-write p)
> (custom-display p))
>
>   (define/public (get-balance)
> balance)
>   (define/public (sprout)
> (send this-mint make-purse 0))
>   (define/public (get-decr)
> (sealer decr))
>
>   (define/public (deposit amount src)
> ((un

Re: Sealers/unsealers in Racket (Re: [racket-users] Questions about module encapsulation guarantees)

2018-09-10 Thread Christopher Lemmer Webber
Matthias Felleisen writes:

>> On Sep 10, 2018, at 10:09 AM, Christopher Lemmer Webber 
>>  wrote:
>>
>> Jack Firth writes:
>>
>>> If I make a symbol with `gensym` (or do anything else that creates a new
>>> value that's not `eq?` to any other value) in some module, what are the
>>> absolute upper limits on my ability to use that symbol within the module
>>> without allowing any other modules to get ahold of the symbol? What do code
>>> inspectors, namespaces, sandboxes, eval, `unsafe` APIs, the FFI, etc. make
>>> possible for malicious code in external modules?
>>>
>>> Context: I'm exploring a "contract witness" idea whose implementation
>>> currently relies on the eq?-ness of opaque struct instances for security.
>>> But I vaguely recall hearing once that the The Only Way To Be Sure when it
>>> comes to struct encapsulation is to put the definition of a struct inside a
>>> lambda, otherwise some sort of nebulous "bad things" are possible in
>>> external code that wants to break the invariants of  a struct type.
>>
>> Struct inside a function is certainly a way to do it.  You may be
>> interested in the idea of sealer/unsealer pairs from the object
>> capability world.  I borrowed the implementation of this from Jonathan
>> Rees' W7 code.  Consider this waived into the public domain, under CC0,
>> but also with any potential patents waived under the same terms.
>
> Does this really differ from Jim Morris’s sealing?

Not only does it not differ, it's cited on the page... this is just
an implementation :)

>From http://erights.org/elib/capability/ode/ode-capabilities.html :

> Two common forms of rights amplification are sibling communication
> [Hardy, Gosling96, Shalit96] and sealer/unsealer pairs [Morris73,
> Miller87, Tribble95 Appendix D, Rees96]. E primitively provides
> sealer/unsealer pairs. The money example below builds sibling
> communication from sealer/unsealer pairs.

which links to:

  http://www.erights.org/history/morris73.pdf

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Sealers/unsealers in Racket (Re: [racket-users] Questions about module encapsulation guarantees)

2018-09-10 Thread Christopher Lemmer Webber
Good call, I'll be careful about that in future examples.

David Storrs writes:

> This is a very cool thing, but may I suggest choosing a different name than
> 'can'?  '(can-unseal lunch)' reads less like a verb and more like a
> predicate where someone forgot the '?' -- "Are you able to unseal lunch?"
> as opposed to "Unseal my lunch now".
>
> On Mon, Sep 10, 2018 at 11:09 AM, Christopher Lemmer Webber <
> cweb...@dustycloud.org> wrote:
>
>> Jack Firth writes:
>>
>> > If I make a symbol with `gensym` (or do anything else that creates a new
>> > value that's not `eq?` to any other value) in some module, what are the
>> > absolute upper limits on my ability to use that symbol within the module
>> > without allowing any other modules to get ahold of the symbol? What do
>> code
>> > inspectors, namespaces, sandboxes, eval, `unsafe` APIs, the FFI, etc.
>> make
>> > possible for malicious code in external modules?
>> >
>> > Context: I'm exploring a "contract witness" idea whose implementation
>> > currently relies on the eq?-ness of opaque struct instances for security.
>> > But I vaguely recall hearing once that the The Only Way To Be Sure when
>> it
>> > comes to struct encapsulation is to put the definition of a struct
>> inside a
>> > lambda, otherwise some sort of nebulous "bad things" are possible in
>> > external code that wants to break the invariants of  a struct type.
>>
>> Struct inside a function is certainly a way to do it.  You may be
>> interested in the idea of sealer/unsealer pairs from the object
>> capability world.  I borrowed the implementation of this from Jonathan
>> Rees' W7 code.  Consider this waived into the public domain, under CC0,
>> but also with any potential patents waived under the same terms.
>>
>> Imagine the ability to make a magical canning kit and a can opener,
>> where the cans produced can only be opened by the respective can opener.
>>
>>   ; Create a new sealer / unsealer pair and sealed? predicate
>>   ; sealer-name is optional and just for debugging help
>>   (define (new-seal [sealer-name #f])
>> (define struct-name
>>   (if sealer-name
>>   (string->symbol (string-append "sealed-by-" (symbol->string
>> sealer-name)))
>>   'sealed))
>> (define-values (struct:seal seal sealed? seal-ref seal-set!)
>>   (make-struct-type struct-name #f 1 0))
>> (define unseal
>>   (make-struct-field-accessor seal-ref 0))
>> (values seal unseal sealed?))
>>
>> Now let's try using it:
>>
>>   (define-values (can-sealer can-unseal can-seal?)
>> (new-seal 'canning-factory))
>>
>> The traditional ocap example is to seal tuna, but I'm vegetarian.
>>
>>   (define lunch (seal "chickpea salad"))
>>
>>   lunch ; #
>>
>> I'm in control of the sealer from my little canning factory, I don't
>> give it to anyone else.  Only someone with the matching unsealer can
>> open this can.  I can safely put it in the fridge.
>>
>> I can make sure this can is my lunch, in case I forgot:
>>
>>   (can-sealed? lunch) ; #t
>>
>> And I can get to its contents:
>>
>>   (can-unseal lunch) ; "chickpea salad"
>>
>> Not that this looks a lot like decryption, but with lexical scope only.
>> It's possible I am okay with someone else opening my objects, in which
>> case I might give them the can-sealed? predicate and the can-unseal
>> procedure... then they can open it, but be sure it's from me.  And
>> with that you can more or less implement signatures.
>>
>> BTW, you can do powerful stuff with this... here's an example where
>> you implement digital money:
>>
>>   http://erights.org/elib/capability/ode/ode-capabilities.html
>>
>> Here's the same example from that article, written in Racket code:
>>
>>   (define (make-mint name)
>> (define-values (sealer unsealer sealed?)
>>   (new-seal name))
>> (define/contract mint%
>>   (class/c [make-purse (->m nonnegative-integer? any/c)])
>>   (class* object% (writable<%>)
>> (super-new)
>> (define/public (custom-display p)
>>   (display (format "#<~a mint>" name) p))
>> (define/public (custom-write p)
>>   (custom-display p))
>>
>> (define this-mint this)
>> (define/public (make-purse balance)
>>   (define/contract (decr amount)
>> (-> (and/c (>=/c 0)
>>(lambda (amt)
>>  (<= amt balance)))
>> void?)
>> (set! balance (- balance amount)))
>>   (define/contract purse%
>> (class/c [get-balance (->m integer?)]
>>  [deposit (->m integer? any/c void?)])
>> (class* object% (writable<%>)
>>   (super-new)
>>
>>   (define/public (custom-display p)
>> (display (format "#" balance name) p))
>>   (define/public (custom-write p)
>> (custom-display p))
>>
>>   (define/public (get-balance)
>> balance)
>>   (define/public (