3 ms·
This is basically what got Ruby with its YAML reader, isn't it? EDIT: I'm not familiar enough with clojure; is read-line supposed to be safe?
by pfraze 14y ago
This is basically what got Ruby with its YAML reader, isn't it?
EDIT: I'm not familiar enough with clojure; is read-line supposed to be safe?
- martinced 14y agoIt's the same issue as long as you consider that any evaluation of unwanted code is the same issue and if you consider that what happens here with the Java constructors is really "eval'ing" code. Here I'd say it's a bit different: it's kinda the whole of having read-eval set to true to be able to evaluate code. So when read-eval is set to false and yet rogue code happens to be called there's a serious issue. Basically the issue is that under the hood some Java constructors seems to be called and, if I understand the issue correctly, by knowing how Clojure works you can exploit Clojure / the JVM by crafting precisely what you want to pass to Java constructors (which shouldn't be called in the first place). Here as I understand it it's not an "eval" exploit per se: it's Java constructors which are passed carefully crafted input.
- benatkin 14y agoThis is read-string, not read-line. It doesn't mean read a string but to read from a string. It reads the first clojure expression from a string. It isn't supposed to be safe, though it can be tempting to treat it as though it's safe. - It's similar to the YAML reader, in that Java objects can be created. See "deftype, defrecord, and constructor calls" here: http://clojure.org/reader http://clojure.org/reader - On the positive side for the clojure reader, it isn't widely described as a serialization format and people are less inclined to use it for user input. This is a pretty important difference. - On the negative side, you can not only instantiate objects, but you can execute code. This is what the example in the article does. You can disable that by setting read-eval. - Also on the negative side, it lacks something quite as secure as YAML's safe_load. You can tell it not to evaluate code, but there isn't yet a way to disable instantiating objects. As puredanger pointed out, EDN is a better alternative that also comes with clojure. It's designed for data. Clojure's code format is a superset of EDN. http://clojure.github.com/clojure/clojure.edn-api.html http://clojure.github.com/clojure/clojure.edn-api.html
- stonemetal 14y agoNot really, read-line is more or less equivalent to python's input method. It reads raw input and tries to evaluate it. Passing false makes it safer for reading data structures, but it will still try to execute Java constructors so that your data is correctly initialized. To be safe you need to use other methods i.e. edn(extensible data notation). edn limits what is allowed to a safe subset of what read-line will allow, all of the base clojure types and collection types (maps, lists, sets, vectors) are allowed, Java isn't.
- mjw 14y ago> It reads raw input and tries to evaluate it Not quite. It reads raw input and tries to build a syntax tree from it. Unfortunately reader macros in clojure allow all sorts of objects to form part of said syntax tree and arbitrary-ish code to run at parse time to instantiate them. But the main job of the reader isn't to evaluate code.