World: r3wp
[!REBOL3]
older newer | first last |
Ladislav 3-May-2011 [8330x6] | http://issue.cc/r3/1881and http://issue.cc/r3/1882submitted |
Regarding the example evaluating words above: lit-path: first ['a(b] do [lype? lit-path] Which result do you prefer? As far as my preferences go, I prefer to obtain the lit-path! datatype | |
Correction: Regarding the example evaluating words above: lit-path: first ['a/b] do [type? lit-path] Which result do you prefer? As far as my preferences go, I prefer to obtain the lit-path! datatypeRegarding the example evaluating words above: lit-path: first ['a(b] do [lype? lit-path] Which result do you prefer? As far as my preferences go, I prefer to obtain the lit-path! datatype lit-path: first ['a/b] do [lype? lit-path] | |
This keyboard is getting me crazy, sorry | |
Correction: Regarding the example evaluating words above: lit-path: first ['a/b] do [type? lit-path] Which result do you prefer? As far as my preferences go, I prefer to obtain the lit-path! datatype | |
(in R3 yout get the lit-path!, while in R2 the path! datatype) | |
Geomol 3-May-2011 [8336] | I prefer lit-path!. The same for lit-words: lit-word: first ['a] do [type? lit-word] I prefer that to return lit-word!. It's only, if the word being looked up (lit-word in this example) is a function (or native, op, action, ...) that further computation should occur, I think. |
Ladislav 3-May-2011 [8337] | Makes sense |
Geomol 3-May-2011 [8338x2] | Actually I ran into problems related to this, when programming the bparse function. At one point, I need to test, if a token variable is equal to the word END. To specify the word END, I write it as a lit-word, because lit-words are changed to words on the run. I need to use == to compare, because I want the type to be the same too. So I would expect, this is the correct test: token == 'end Let's test: >> token: first [end] == end >> token == 'end == true Seems to work, but then the surprise, if token is a lit-word: >> token: first ['end] == 'end >> token == 'end == true Also true? Hmm, so I have to write: >> :token == 'end == false |
The above is done in R2. | |
BrianH 3-May-2011 [8340x6] | Strangely enough, with http://issue.cc/r3/1882you are proposing to do the opposite of http://issue.cc/r3/1881 |
In #1881 you are proposing to take what in R3 is currently an active value and render it inactive, which will make it mildly safer to handle - lit-word/lit-path conversion to word/path is a trivial thing. In #1882 you are proposing to make the word! type into an active value, where you would have to treat every word value as carefully as you treat the function it is assigned. Except it's worse, because in R2 it has the effect of doing *blocks* as well, if those blocks are assigned to a word - even DO of an inline word isn't that unsafe. It is really bad. | |
Please, be consistent here. If you accept #1881, please reject #1882, for our own safety. | |
Oh wait, I misread #1881, I thought it was the lit-path thing. Never mind, it's unsafe too. | |
I noticed when you did the poll, you used a safe function that you knew the source of. Do the poll again with a function that deletes your hard drive, or even a block of code for some other dialect that will coincidentally do damage when interpreted by the DO dialect (since R2 does this with blocks and parens as well). Or even a function that takes an unknown number of parameters, and put the call in the middle of code that might be affected by evaluation order or get-word hacking. | |
Most of you might not remember this, but parens used to be treated as active values in R2. If you had a paren assigned to a word, putting that word inline in a DO dialect block would cause the paren to be executed. I used to use this as a way of having quick thunks (functions that take no parameters) without calling DO explicitly. However, this made it difficult to work with paren values, and was eventually removed for security reasons because it made screening for potentially dangerous values more difficult than a simple ANY-FUNCTION? call. It would be bad to make word! and path! values just as difficult to work with. | |
Ladislav 3-May-2011 [8346] | In #1881 you are proposing to take what in R3 is currently an active value and render it inactive - do I? |
BrianH 3-May-2011 [8347x3] | No, I mistokk what you were saying, and corrected myself in the "Oh wait" message. |
#1434, #1881 and #1882 now have clarifying comments. | |
Btw, this comment in #1882: "and since you've requested that lit-word! and lit-path! be returned to their R2-style inconsistency" may not be an accurate representation of your proposal (here earlier in conversation). You might be proposing that R3 do a better job at being inconsistent than R2 is doing (as demonstrated in #1434). If so, cool. | |
Gregg 3-May-2011 [8350] | I prefer convenience, but understand the concerns about security. Less aggressive evaluation by DO doesn't solve the security problem though, does it? If we say "Never DO untrusted data", DO can provide more convenience. Of course, that means it may be less convenient if you have to evaluate untrusted data, but at least the line is clear. |
Geomol 3-May-2011 [8351] | >> o: make object! [f: does [42]] >> do in o 'f ; This is a problem, as nothing seems to be happening! >> o/f == 42 I'm not sure, I understand the security concern. |
Ladislav 4-May-2011 [8352x3] | Frankly, there is no security problem which can be influenced by this. |
Stating otherwise is just pretending | |
If somebody wants to use DO, he is responsible for knowing what he is doing | |
BrianH 4-May-2011 [8355x2] | Pretending that security doesn't matter is a worse policy. Here is what would resolve the security issue: - Putting warnings in the docs for DO, in the same section where they talk about the special treatment of functions and blocks. - Make parameters not work, and don't do blocks and parens through word values, same as R2's DO of path values. - Make sute that we don't try to make set-words and set-paths do assignment when you DO them. Treat them like get-words and get-paths. Together, those restrictions would make DO of word and path values no more insecure than DO of block and paren values. For functions, we have APPLY. |
sute -> sure | |
Maxim 4-May-2011 [8357] | btw, I've been using apply in R2.7.8 and it works really well :-) |
BrianH 4-May-2011 [8358] | DO of block and paren values is something that we can say is secure enough already, assuming that variables and such are protected and secured, so that is a good set of restrictions to follow for words and paths. Calling functions through inline words is secure enough if you can control the binding and writeablility of those words. DO of function values has the argument problem, but it's known and has built-in workarounds (APPLY, putting function calls in parens), and we already have simple ways to screen for them. |
Gregg 4-May-2011 [8359x2] | DO is seductive, because sometimes I want to create (easily) a "dialect environment" and just use DO to evaluate my dialect., safely and securely. Is there a security page in the docs (I don't see one in the R3 docs right now)? If not, that would be good to have. If we have a list of functions and operations you shouldn't use on untrusted data, and what the risks are, that's a good start. |
And, as Brian mentions, having workarounds or being able to screen for exploitable features. | |
Sunanda 4-May-2011 [8361] | I'd still like to see the sort of safe evaluation as dreamt of in this older ML thread: http://www.rebol.org/ml-display-thread.r?m=rmlNVBC |
BrianH 4-May-2011 [8362x2] | There isn't much of a security page right now, though it would be a good idea to make one if only to document the stuff that doesn't currently work (like SECURE in the last 4 versions). I don't know if anyone else has made a concerted effort to attack REBOL and then fix the security problems found. |
I would love it if we as a community were to really think through the (UN)PROTECT model, because the current model is incomplete (even for the stuff that works) and the proposed model is starting to look a bit awkward to use. Keep in mind that PROTECT may also be used to make series sharable among tasks, but that this isn't implemented and there is likely a better way to do this. I would love it if there was a good security model that can integrate well with REBOL semantics. | |
Kaj 4-May-2011 [8364] | Capabilities |
BrianH 4-May-2011 [8365] | Won't work within a process, only on a process boundary. |
Kaj 4-May-2011 [8366] | Depends on if you make it work |
BrianH 4-May-2011 [8367] | It's inherent in the semantics of REBOL, a side effect of the code-vs-data thing. |
Kaj 4-May-2011 [8368] | Do you know the Genode architecture? |
BrianH 4-May-2011 [8369] | That might work for SECURE but not for (UN)PROTECT. |
Kaj 4-May-2011 [8370] | Why not? |
BrianH 4-May-2011 [8371] | (I am trying to write a long *starting* message here and have to put it in the clipboard to answer these questions, sorry.) |
Kaj 4-May-2011 [8372] | That's OK, I'm interested in your opinion. I haven't formulated an answer for myself yet |
BrianH 4-May-2011 [8373] | Some factors to consider about the REBOL semantic limitations: - There is no such thing as trusted-vs-untrusted code in a REBOL process, nor can there be, really. Levels of trust need to be on a process boundary. You can't (even hypothetically) do LOAD/secure level or DO/secure level, but you can do LAUNCH/secure level. - If you want to make something readable or writeable to only certain code within a process, binding visibility tricks are the only way to do it. The only way to ensure that your code has access to something and other code doesn't is to make sure that other code can't even see yours. This is why BODY-OF function returns an unbound copy of the body in R3, not the original. - We need a way to make protection stick so you can't unprotect things that are protected, or protect things that need to stay unprotected, but still allow changes to the protection status of other stuff. The currently proposed model does this through a chain of PROTECT and UNPROTECT calls, then a PROTECT/lock, not allowing unlocking if there is a SECURE 'protect. However, the proposed model seems too difficult to use, and as the pre-110 module system demonstrated, people won't use something that is too complex to use, or will use it badly. We need a better way of specifying this stuff. |
Kaj 4-May-2011 [8374x3] | OK, that's the current REBOL model, but you asked about alternative models. Capabilities are not about trust levels, but about capability tokens. They're meant to take trust out of the equation |
Trying to hammer every hole shut with SECURE and PROTECT is the classic method of sticking all your fingers in the dike. When you run out of fingers for all the holes, the water comes gushing in. Capabilities are about making it impossible to get through the next dike. It's a different way of compartmentalising | |
An E language fan once visited Carl to explain to him that true capabilities can be implemented in REBOL very well. Carl apparently rejected it based on complexity, but if the problem with the current new R3 method is rising complexity, maybe this decision is worth reviewing | |
BrianH 4-May-2011 [8377x3] | Now, for your questions, Kaj. Mezzanines execute arbitrary code with DO. You can't even know if something is code or not until you pass it to a dialect interpreter like DO or PARSE - code is data. Blocks don't have bindings, only their any-word contents do, so the code blocks of functions are not bound to functions, only their contents are. The same goes for functions in modules or objects - they aren't bound to their objects or modules, only referenced by them. (making this up on the fly) It could be possible to make the binding visibility of words be defined as a set of capability tokens as part of the object spec (in the SPEC-OF sense), and have the function spec dialect be extended to contain such tokens. This would have to be checked with every word access, and we would have to be careful to make the model in such a way to avoid unauthorized privilege escalation. Then changes in capabilities would happen on the function call stack, which is task-specific. The problem with this is making sure code can't make functions with more capabilities than the code making them currently possesses. Though R3 doesn't really have a user model, it does have a task model and we could make the capability level task-specific. Code could constrain capabilities for code it calls, but we don't want privilege escalation at function creation time. It would be possible to have privilege escalation at function call time if the function called was created by something with the necessary capabilities. Drawbacks: - If we do this for binding visibility, this means a capabilities check would go into every word access. Word access would be SLOW. - This doesn't add anything to the PROTECT/hide model, which handles binding visibility without the slowdown. Capabilities would be like the SECURE model, but more flexible, so that's something to consider there. What SECURE protects is heavy enough that a capabilities check wouldn't add much to the overhead. |
Remember, R3 currently has three separate security models: SECURE, (UN)PROTECT, and PROTECT/hide. | |
Of the 3, SECURE seems like the most likely to be enhanceable with capabilities. Functions could be enhanced by capabilities specs, where the function code could only create other functions of equal to or lesser capabilities than are currently available in the call stack. Once a function is created, it could run code with the capabilities that it was created with (with the exception of that function creation limitation earlier). There could be a function like DO that reduces capabilities and then does a block of code, and maybe MAKE module! could be made to use that function based on capabilities in the module spec. | |
older newer | first last |