REBOL3 tracker
  0.9.12 beta
Ticket #0001893 User: anonymous

Project:



rss
TypeBug Statusbuilt Date10-Oct-2011 18:32
Versionalpha 111 CategoryNative Submitted byBrianH
PlatformAll Severityminor Prioritynormal

Summary BIND stuff function-bound-word restriction has no benefit, should be removed
Description BIND has a few restrictions for security purposes, a couple of which apply to function! contexts. One of these restricts code practically without having the intended security benefit. It is a bad tradeoff which we would be better off removing.

For practical reasons we allow BIND to bind to a word bound to a function context when the function is running (see #216), but but we didn't allow it when the function wasn't running for security reasons IIRC. However, Ladislav has demonstrated that this restriction has no security benefit, as demonstrated in the example code here (translating his argument into REBOL). All it does is inconvenience developers of even slightly advanced code.

The other security restrictions - no BIND to a function! value, BODY-OF returning an unbound copy - are still effective, as demonstrated in the comments. So is the practice of unbinding words before they're leaked, or not leaking them at all.
Example code
; Leaking a bound word could be a security problem
>> object [h: "something you want" protect/hide 'h set 'f func [x /a] [a: h x 'a]]
>> f 1
== a
; But it isn't for functions when they aren't running because their context isn't there
>> get f 1
** Script error: a word is not bound to a context
** Where: get
** Near: get f 1

; Leaking a different word
>> object [h: "something you want" protect/hide 'h set 'f func [x /a] [a: h x 'x]]
; Is supposedly less of a security problem because of an extra restriction
>> get bind 'a f 1
** Script error: a is not in the specified context
** Where: bind
** Near: bind 'a f 1
; But it's unnecessary because the first restriction above works in this case already

; And neither restriction is secure at all if you can make code run while the function runs
>> object [h: "something you want" protect/hide 'h set 'f func [x /a] [a: h x 'x]]
>> b: f 1
== x
>> f does [print get bind 'a b]
something you want
== x
; Even worse if you pass in a function that takes an argument, only one call needed
>> f func [arg] [print get bind 'a arg arg]
something you want
== x

Assigned ton/a Fixed inr3 master Last Update5-Mar-2014 09:06


Comments
(0003207)
BrianH
10-Oct-2011 18:39

There is still a valid security benefit to preventing BIND from binding to the function! value itself, as the example code below demonstrates. With that restriction, you can prevent access to a function context by not leaking bound function words, and still safely provide access to the function itself. And binding to a closure! still makes no sense - it's not just a bad idea, it has no meaning since the closure creates a new context every time it runs, rather than having a context of its own.

; The best security practice is to not leak bound words at all
>> object [h: "something you want" protect/hide 'h set 'f func [x /a] [a: h x]]
; We have no access to a bound word now, so try to bind to the function
>> f does [print get bind 'a :f]
** Script error: bind does not allow function! for its context argument
** Where: x f
** Near: x
; Doesn't work, disallowing BIND something function! is effective
; Let's try getting from the already-bound word in the source
>> print get second body-of :f
** Script error: h word is not bound to a context
** Where: get
** Near: get second body-of :f
; Didn't work, BODY-OF unbinding is effective

; Or we can unbind the words before leaking them
>> object [h: "something you want" protect/hide 'h set 'f func [x /a] [a: h x unbind 'x]]
>> b: f 1
== x
>> f does [print get bind 'a b]
** Script error: x word is not bound to a context
** Where: bind x f
** Near: bind 'a b

; Unbinding is even effective when you return the word directly, normally even worse
>> object [h: "something you want" protect/hide 'h set 'f func [x /a] [a: h x 'a]]
>> b: f 1
== a
>> f does [print get b] ; Doesn't even need BIND
something you want
== a
; But unbind it and you're safe
>> object [h: "something you want" protect/hide 'h set 'f func [x /a] [a: h x unbind 'a]]
>> b: f 1
== a
>> f does [print get b]
** Script error: a word is not bound to a context
** Where: get x f
** Near: get b
(0003208)
Ladislav
10-Oct-2011 23:34

"...binding to a closure! still makes no sense..." - yes, this can even be used as a supporting argument why binding to a function! should not be allowed either (possible compatibility problems).

Also, binding to a closure local (parameter) word does make sense, and it is allowed, so, compatibly, binding to a function parameter word should be allowed as well.

And, indeed, disabling binding to function parameter words when the function isn't running does not bring any security benefit at all.
(0003250)
BrianH
6-Dec-2012 19:51

#1914 is related.
(0003905)
Ladislav
30-Jul-2013 09:08

In the core-tests suite.
(0003911)
Ladislav
5-Aug-2013 15:23

Fixed by https://github.com/rebol/rebol/pull/123

Date User Field Action Change
5-Mar-2014 09:06 BrianH Status Modified pending => built
5-Mar-2014 09:06 BrianH Fixedin Modified => r3 master
19-Aug-2013 08:33 Ladislav Comment : 0003911 Modified -
13-Aug-2013 16:22 Ladislav Status Modified submitted => pending
5-Aug-2013 15:23 Ladislav Comment : 0003911 Added -
30-Jul-2013 09:08 Ladislav Comment : 0003905 Added -
30-Jul-2013 09:03 Ladislav Comment : 0003208 Modified -
6-Dec-2012 19:51 BrianH Comment : 0003250 Added -
10-Oct-2011 23:40 Ladislav Comment : 0003208 Modified -
10-Oct-2011 23:34 Ladislav Comment : 0003208 Added -
10-Oct-2011 19:00 BrianH Code Modified -
10-Oct-2011 18:58 BrianH Code Modified -
10-Oct-2011 18:54 BrianH Code Modified -
10-Oct-2011 18:52 BrianH Comment : 0003207 Modified -
10-Oct-2011 18:52 BrianH Comment : 0003207 Modified -
10-Oct-2011 18:45 BrianH Description Modified -
10-Oct-2011 18:40 BrianH Code Modified -
10-Oct-2011 18:40 BrianH Description Modified -
10-Oct-2011 18:39 BrianH Comment : 0003207 Added -
10-Oct-2011 18:32 BrianH Ticket Added -