World: r3wp
[!REBOL3]
older newer | first last |
Ladislav 9-Oct-2011 [9662] | To remind you, I am and was always referring to this: >> f: func [a b] ['a] >> bind [b] f 1 2 ** Script error: none word is not bound to a context ** Where: bind ** Near: bind [b] f 1 2 The above is unrelated |
BrianH 9-Oct-2011 [9663] | No, the above is the exact reason for: >> not find second types-of :bind function! == true |
Ladislav 9-Oct-2011 [9664x2] | No... - still unrelated |
But, the reasons for disallowing the functions as the BIND arguments have actually a similar flaw. | |
BrianH 9-Oct-2011 [9666] | a: func [code /stuff] [stuff: "something secret, not a literal string" code] With just a reference to :a, bind 'stuff to the function context. The function could be running or not when you get access to the bound word 'stuff. The exploit code can then be passed to the function in its code argument, which would then have access to the contents of 'stuff because the function is running. |
Ladislav 9-Oct-2011 [9667] | your example is too trivial. I get the access to the "something secret..." too easily, jut by examining the function body. Don't you have anything more complicated? |
BrianH 9-Oct-2011 [9668x2] | This is the reason for that particular restriction. If there's a workaround that we don't yet know about, let us know so we can plug it. |
That was just a placeholder. The stuff variable could be the results of a prompt to the user for their password, or of a native function that decrypts something. One problem at a time. | |
Ladislav 9-Oct-2011 [9670] | As said, problem solved. You need something nontrivial to throw at me. |
BrianH 9-Oct-2011 [9671] | No, seriously, I meant it. How do you do this without BIND 'stuff :a ? |
Ladislav 9-Oct-2011 [9672x2] | As said, I do not have to. The string is already there for me to read. |
Your trouble is, that you do not see, that the triviality of your problem matters. | |
BrianH 9-Oct-2011 [9674] | Ignore the particular literal value there, and substitute it with something that outside code can't otherwise get access to, like the results of a call to a function that is referred to by a PROTECT/hide variable. |
Ladislav 9-Oct-2011 [9675x2] | I cannot, it is up to you to find *any* meaningful example, which I am maintaining is impossible. |
It is you failing to provide a reason, and, I am actually able to prove there is none. | |
BrianH 9-Oct-2011 [9677] | If getting access to 'stuff is the only way to get access to what it refers to, how do you get access to 'stuff if all you have is :a ? |
Ladislav 9-Oct-2011 [9678x2] | Any example? |
As said, using the properties of REBOL functions, I can easily prove you wrong in any case you invent. | |
BrianH 9-Oct-2011 [9680] | blah: module [] [hidden hidden-stuff: "something you want" a: func [code /stuff] [stuff: hidden-stuff code]] blah/a func [] [do something to get access to hidden-stuff] |
Ladislav 9-Oct-2011 [9681x2] | OK, fine, an example that looks meaningful to you. |
So, do I assume correctly, that I cannot examine the BLAH module to get the HIDDEN-STUFF value? | |
BrianH 9-Oct-2011 [9683] | It's just a placeholder. If you have a PROTECT/hide exploit, that's interesting too but off-topic. |
Ladislav 9-Oct-2011 [9684] | Does not matter, it is just an assumption, I am just asking whether you don't mind me making it. |
BrianH 9-Oct-2011 [9685x3] | Right. Let me make that more explicit: import module [] [hidden hidden-stuff: "something you want" export a: func [code /stuff] [stuff: hidden-stuff code]] |
In those circumstances a reference to :a is copied to lib/a, but there is no reference to the module saved except the PROTECT/hide reference to hidden-stuff in the block of :a. | |
Or rather it's copied to system/contexts/user/a, but the point remains the same. | |
Ladislav 9-Oct-2011 [9688x2] | Yes, OK. So, now, let me cite: The reason for this is so that functions can prevent access to their context from leaking to code *that the function calls* that could be exploited while the function is running. - don't you see, that your purported reason fails? |
Why it fails: because, even knowing the bound version of the 'stuff variable does not help me to get the HIDDEN-STUFF, so, the purported reason does not exist | |
BrianH 9-Oct-2011 [9690] | a func [] [do something to get access to hidden-stuff] The function a doesn't exclude functions from its arguments and it refers to its argument with a word rather than a get-word, so it can be tricked into running code while it is running. That means its context is valid while the exploit code is running. |
Ladislav 9-Oct-2011 [9691] | So, once again, your example demonstrating the existence of the (purported and nonexistent) reason failed. |
BrianH 9-Oct-2011 [9692x2] | The 'stuff word isn't hidden, but it isn't leaked while the function is running. That means that the exploit code only has access to the :a function value. |
So, come up with some exploit code (that doesn't use STACK because we're assuming SECURE 'debug works). This is a real problem. | |
Ladislav 9-Oct-2011 [9694] | Do I understand correctly, that this is what you propose as demonstrating the reason for the functions not being accepted by BIND? a: func [] [do something to get access to hidden-stuff] |
BrianH 9-Oct-2011 [9695] | No, you added a : there. The function is being passed to a as an argument. |
Ladislav 9-Oct-2011 [9696] | aha, sorry, now I see. |
BrianH 9-Oct-2011 [9697x2] | a func [] [print get bind 'stuff :a] |
I had to go though the mezzanine code pretty carefully to consider what happens when functions are passed as arguments to the mezzanine functions. Some functions like REPLACE and ARRAY were modified to take advantage of that trick pretty nicely. | |
Ladislav 9-Oct-2011 [9699] | OK, but nothing of that kind applies to the case of BIND [...] 'some-variable |
BrianH 9-Oct-2011 [9700x2] | True, which is why I was convinced by that particular argument :) |
then the ban on BIND to a function-context-bound word when the function isn't running has no security benefit :) | |
Ladislav 9-Oct-2011 [9702] | Yes, it only prevents some meaningful uses |
BrianH 9-Oct-2011 [9703] | Especially ones where the bound words are leaked intentionally to provide access to the context. It sounds worthy of a wish ticket in CureCode. |
Ladislav 9-Oct-2011 [9704] | Unfortunately, the whole issue may be quite long to present completely |
BrianH 9-Oct-2011 [9705] | I'll write it up, if it's OK to copy some of your arguments from above into the ticket. |
Ladislav 9-Oct-2011 [9706x2] | Anything |
So, for the case of BIND [...] function the main difference is, that it cannot be done regardless of whether the function is running or not, which can be considered a security measure, then. | |
BrianH 9-Oct-2011 [9708] | Yup. And BODY-OF returning an unbound copy prevents code like this: print get second body-of :a PROTECT/hide doesn't affect existing bindings, so you need to be careful about leaking those too. |
BrianH 10-Oct-2011 [9709] | Initial version of the ticket made: http://issue.cc/r3/1893 |
Ladislav 10-Oct-2011 [9710] | Supporting comment added. |
Henrik 11-Oct-2011 [9711] | would it not be practical if REMOVE-EACH could /SKIP ? |
older newer | first last |