Type | Bug | Status | built | Date | 10-Oct-2011 18:32 |
---|---|---|---|---|---|
Version | alpha 111 | Category | Native | Submitted by | BrianH |
Platform | All | Severity | minor | Priority | normal |
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 to | n/a | Fixed in | r3 master | Last Update | 5-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 | - |