Re: *read-eval* vulnerability
Hi all, It looks like Rich has selected an approach to addressing *read-eval*, #=, and related issues. The sands may still be shifting a bit, but far less than e.g. earlier this week. With that in mind, I thought it might be helpful to point to three authoritative messages from the clojure-dev ML that describe various relevant changes and additions coming in 1.5.0. The first one contains a summary of the general principles involved, but note that the default mode described therein didn't last, as described in the second message: http://groups.google.com/group/clojure-dev/msg/786c689b596bb6a3 http://groups.google.com/group/clojure-dev/msg/f299efc525f096e2 http://groups.google.com/group/clojure-dev/msg/8b572b8ebaba2ff5 Most relevant to the tactical concern of this thread (the default value of *read-eval* and its implications) is the new ability to set that default via a Java system property. Hopefully the above satiates anyone yearning for news on this topic until the 1.5.0 changelog is updated to reflect the relevant changes. Finally, I just wanted to thank everyone, for your attention, energy, enthusiasm, and brilliance. It's an honor to be among you. Cheers, - Chas -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: *read-eval* vulnerability
Hi Baishampayan, I got such errors when I first started working on the patch; they were caused by the compiler using print-dup'd strings to create namespaces instead of emitting bytecode (which the patched build includes). Is it possible that you have both an org.clojure/clojure jar and the patched com.cemerick/clojure jar on your classpath? FWIW, such metadata happens to exist in some nREPL namespaces, and some of my projects as well, so I presume that that's not the actual problem. Just out of curiosity, do things work well if you use e.g. inferior-lisp or ritz? Thanks for testing! - Chas On Feb 1, 2013, at 11:10 PM, Baishampayan Ghose wrote: Just did some testing with our code-base and Clojure 1.5.0-RC4 (with and without Chas' read-eval patch). There is definitely something strange going on. Things worked just fine with 1.5.0-RC4 but with the read-eval patch `lein swank` is completely broken but more than that, our code is failing to compile with this weird error - eval-reader: (clojure.lang.PersistentArrayMap/create {:author Joe Dev j...@helpshift.com, :doc Some doc here.}) RuntimeException EvalReader not allowed when *read-eval* is false. clojure.lang.Util.runtimeException (Util.java:219) Almost all our namespaces have documentation attached via metadata like this - (ns ^{:doc Some doc here. :author Joe Dev j...@helpshift.com} com.helpshift.some.ns (:require [com.helpshift.other.ns :as chon]) (:use clojure.test midje.sweet)) FWIW, the file that will fail to compile is random and I couldn't reproduce this error on a fresh project with just a couple of files. It's quite clear that the eval-reader is getting used from inside Clojure and we need to test out the edge cases a bit more. This is clearly not a low-impact fix, but IMHO we should take the time and get it right before 1.5.0 Regards, BG On Sat, Feb 2, 2013 at 4:01 AM, Chas Emerick c...@cemerick.com wrote: I have added a patch to CLJ-1153 that appears to address the *read-eval* problem: http://dev.clojure.org/jira/browse/CLJ-1153?focusedCommentId=30523#comment-30523 code on github: https://github.com/cemerick/clojure/commit/1f5c19c07443d2535ede4ff71d23b40c195d617f artifact on Clojars: [com.cemerick/clojure 1.5.0-SNAPSHOT] The Leiningen dependency above is 1.5.0-RC4 + the patch on the ticket. Note that you'll need to set your project's global :exclusions to [org.clojure/clojure] in order for the com.cemerick/clojure artifact to supersede it. It tests well for me, but needs to be exercised as much as possible. Some have already done so (there's an ongoing discussion on the clojure-dev ML with some initial test experiences: http://groups.google.com/group/clojure-dev/browse_frm/thread/cc6f747919db6c94), but I'm hoping that we can get as many eyes as possible on this — doing both testing as well as code/patch examination — so as to ensure correctness and maximize the chances of 1.5.0 final going out with this vulnerability buttoned up. Thanks, - Chas -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- Baishampayan Ghose b.ghose at gmail.com -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You
Re: *read-eval* vulnerability
I put the canonical clojure artefact in a global exclusions vector in my project.clj. The classpath doesn't have any duplicate clojure jar in it. I was testing it out with `lein repl`, since swank-clojure is broken in different ways. Regards, BG On Sat, Feb 2, 2013 at 7:43 PM, Chas Emerick c...@cemerick.com wrote: Hi Baishampayan, I got such errors when I first started working on the patch; they were caused by the compiler using print-dup'd strings to create namespaces instead of emitting bytecode (which the patched build includes). Is it possible that you have both an org.clojure/clojure jar and the patched com.cemerick/clojure jar on your classpath? FWIW, such metadata happens to exist in some nREPL namespaces, and some of my projects as well, so I presume that that's not the actual problem. Just out of curiosity, do things work well if you use e.g. inferior-lisp or ritz? Thanks for testing! - Chas On Feb 1, 2013, at 11:10 PM, Baishampayan Ghose wrote: Just did some testing with our code-base and Clojure 1.5.0-RC4 (with and without Chas' read-eval patch). There is definitely something strange going on. Things worked just fine with 1.5.0-RC4 but with the read-eval patch `lein swank` is completely broken but more than that, our code is failing to compile with this weird error - eval-reader: (clojure.lang.PersistentArrayMap/create {:author Joe Dev j...@helpshift.com, :doc Some doc here.}) RuntimeException EvalReader not allowed when *read-eval* is false. clojure.lang.Util.runtimeException (Util.java:219) Almost all our namespaces have documentation attached via metadata like this - (ns ^{:doc Some doc here. :author Joe Dev j...@helpshift.com} com.helpshift.some.ns (:require [com.helpshift.other.ns :as chon]) (:use clojure.test midje.sweet)) FWIW, the file that will fail to compile is random and I couldn't reproduce this error on a fresh project with just a couple of files. It's quite clear that the eval-reader is getting used from inside Clojure and we need to test out the edge cases a bit more. This is clearly not a low-impact fix, but IMHO we should take the time and get it right before 1.5.0 Regards, BG On Sat, Feb 2, 2013 at 4:01 AM, Chas Emerick c...@cemerick.com wrote: I have added a patch to CLJ-1153 that appears to address the *read-eval* problem: http://dev.clojure.org/jira/browse/CLJ-1153?focusedCommentId=30523#comment-30523 code on github: https://github.com/cemerick/clojure/commit/1f5c19c07443d2535ede4ff71d23b40c195d617f artifact on Clojars: [com.cemerick/clojure 1.5.0-SNAPSHOT] The Leiningen dependency above is 1.5.0-RC4 + the patch on the ticket. Note that you'll need to set your project's global :exclusions to [org.clojure/clojure] in order for the com.cemerick/clojure artifact to supersede it. It tests well for me, but needs to be exercised as much as possible. Some have already done so (there's an ongoing discussion on the clojure-dev ML with some initial test experiences: http://groups.google.com/group/clojure-dev/browse_frm/thread/cc6f747919db6c94), but I'm hoping that we can get as many eyes as possible on this — doing both testing as well as code/patch examination — so as to ensure correctness and maximize the chances of 1.5.0 final going out with this vulnerability buttoned up. Thanks, - Chas -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- Baishampayan Ghose b.ghose at gmail.com -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group,
Re: *read-eval* vulnerability
By the way, this is how swank-clojure 1.4.4 is failing to compile with the patched clojure jar - Exception in thread main java.lang.IllegalArgumentException: No matching ctor found for class clojure.lang.Compiler$CompilerException, compiling:(swank/commands/basic.clj:183:24) at clojure.lang.Compiler.analyzeSeq(Compiler.java:6607) at clojure.lang.Compiler.analyze(Compiler.java:6401) at clojure.lang.Compiler.analyzeSeq(Compiler.java:6588) at clojure.lang.Compiler.analyze(Compiler.java:6401) at clojure.lang.Compiler.analyze(Compiler.java:6362) at clojure.lang.Compiler$ThrowExpr$Parser.parse(Compiler.java:2306) at clojure.lang.Compiler.analyzeSeq(Compiler.java:6600) at clojure.lang.Compiler.analyze(Compiler.java:6401) at clojure.lang.Compiler.analyze(Compiler.java:6362) at clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:5748) at clojure.lang.Compiler.analyzeSeq(Compiler.java:6600) at clojure.lang.Compiler.analyze(Compiler.java:6401) at clojure.lang.Compiler.analyze(Compiler.java:6362) at clojure.lang.Compiler$IfExpr$Parser.parse(Compiler.java:2679) at clojure.lang.Compiler.analyzeSeq(Compiler.java:6600) at clojure.lang.Compiler.analyze(Compiler.java:6401) at clojure.lang.Compiler.analyzeSeq(Compiler.java:6588) at clojure.lang.Compiler.analyze(Compiler.java:6401) at clojure.lang.Compiler.analyze(Compiler.java:6362) at clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:5748) at clojure.lang.Compiler$TryExpr$Parser.parse(Compiler.java:2158) at clojure.lang.Compiler.analyzeSeq(Compiler.java:6600) at clojure.lang.Compiler.analyze(Compiler.java:6401) at clojure.lang.Compiler.analyze(Compiler.java:6362) at clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:5748) at clojure.lang.Compiler$FnMethod.parse(Compiler.java:5179) at clojure.lang.Compiler$FnExpr.parse(Compiler.java:3753) at clojure.lang.Compiler.analyzeSeq(Compiler.java:6598) at clojure.lang.Compiler.analyze(Compiler.java:6401) at clojure.lang.Compiler.analyze(Compiler.java:6362) at clojure.lang.Compiler$InvokeExpr.parse(Compiler.java:3575) at clojure.lang.Compiler.analyzeSeq(Compiler.java:6602) at clojure.lang.Compiler.analyze(Compiler.java:6401) at clojure.lang.Compiler.analyze(Compiler.java:6362) at clojure.lang.Compiler$TryExpr$Parser.parse(Compiler.java:2129) at clojure.lang.Compiler.analyzeSeq(Compiler.java:6600) at clojure.lang.Compiler.analyze(Compiler.java:6401) at clojure.lang.Compiler.analyze(Compiler.java:6362) at clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:5748) at clojure.lang.Compiler$LetExpr$Parser.parse(Compiler.java:6049) at clojure.lang.Compiler.analyzeSeq(Compiler.java:6600) at clojure.lang.Compiler.analyze(Compiler.java:6401) at clojure.lang.Compiler.analyzeSeq(Compiler.java:6588) at clojure.lang.Compiler.analyze(Compiler.java:6401) at clojure.lang.Compiler.analyzeSeq(Compiler.java:6588) at clojure.lang.Compiler.analyze(Compiler.java:6401) at clojure.lang.Compiler.analyzeSeq(Compiler.java:6588) at clojure.lang.Compiler.analyze(Compiler.java:6401) at clojure.lang.Compiler.access$100(Compiler.java:39) at clojure.lang.Compiler$LetExpr$Parser.parse(Compiler.java:6013) at clojure.lang.Compiler.analyzeSeq(Compiler.java:6600) at clojure.lang.Compiler.analyze(Compiler.java:6401) at clojure.lang.Compiler.analyzeSeq(Compiler.java:6588) at clojure.lang.Compiler.analyze(Compiler.java:6401) at clojure.lang.Compiler.analyze(Compiler.java:6362) at clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:5748) at clojure.lang.Compiler$FnMethod.parse(Compiler.java:5179) at clojure.lang.Compiler$FnExpr.parse(Compiler.java:3753) at clojure.lang.Compiler.analyzeSeq(Compiler.java:6598) at clojure.lang.Compiler.analyze(Compiler.java:6401) at clojure.lang.Compiler.analyzeSeq(Compiler.java:6588) at clojure.lang.Compiler.analyze(Compiler.java:6401) at clojure.lang.Compiler.access$100(Compiler.java:39) at clojure.lang.Compiler$DefExpr$Parser.parse(Compiler.java:531) at clojure.lang.Compiler.analyzeSeq(Compiler.java:6600) at clojure.lang.Compiler.analyze(Compiler.java:6401) at clojure.lang.Compiler.analyzeSeq(Compiler.java:6588) at clojure.lang.Compiler.analyze(Compiler.java:6401) at clojure.lang.Compiler.analyze(Compiler.java:6362) at clojure.lang.Compiler$InvokeExpr.parse(Compiler.java:3626) at clojure.lang.Compiler.analyzeSeq(Compiler.java:6602) at clojure.lang.Compiler.analyze(Compiler.java:6401) at clojure.lang.Compiler.analyze(Compiler.java:6362) at clojure.lang.Compiler.compile1(Compiler.java:7185) at clojure.lang.Compiler.compile(Compiler.java:7255) at clojure.lang.RT.compile(RT.java:389) at clojure.lang.RT.load(RT.java:429) at clojure.lang.RT.load(RT.java:402) at clojure.core$load$fn__5043.invoke(core.clj:5520) at clojure.core$load.doInvoke(core.clj:5519) at clojure.lang.RestFn.invoke(RestFn.java:408) at clojure.core$load_one.invoke(core.clj:5326) at clojure.core$load_lib$fn__4992.invoke(core.clj:5365) at clojure.core$load_lib.doInvoke(core.clj:5364) at clojure.lang.RestFn.applyTo(RestFn.java:142) at
Re: *read-eval* vulnerability
Ah, I didn't grok that you were reporting two separate breakages (one in swank, one in your app). I think the problem is in how the lein-swank plugin sets up dependencies (or, how Leiningen itself applies :exclusions). If you don't have an org.clojure/clojure dependency in your project, then lein-swank will add one, its default (v1.2.1). In this case, I found I did have two clojure jars; my 1.5.0-SNAPSHOT, and [org.clojure/clojure 1.2.1]. This explains the bizarre message of No matching ctor found for class clojure.lang.Compiler$CompilerException. In my verification of swank, I ended up just temporarily swapping the com.cemerick/clojure build in where the official RC4 sits in ~/.m2/repository; once I did that, swank was happy. I haven't yet been able to duplicate the other fault you saw. If it was really due to namespace metadata, then `lein repl` wouldn't ever start, given clojure.tools.nrepl.server's namespace metadata (https://github.com/clojure/tools.nrepl/blob/master/src/main/clojure/clojure/tools/nrepl/server.clj). I wonder if you could produce a cut-down example that exhibits the issue repeatably? Thanks, - Chas On Feb 2, 2013, at 9:22 AM, Baishampayan Ghose wrote: I put the canonical clojure artefact in a global exclusions vector in my project.clj. The classpath doesn't have any duplicate clojure jar in it. I was testing it out with `lein repl`, since swank-clojure is broken in different ways. Regards, BG On Sat, Feb 2, 2013 at 7:43 PM, Chas Emerick c...@cemerick.com wrote: Hi Baishampayan, I got such errors when I first started working on the patch; they were caused by the compiler using print-dup'd strings to create namespaces instead of emitting bytecode (which the patched build includes). Is it possible that you have both an org.clojure/clojure jar and the patched com.cemerick/clojure jar on your classpath? FWIW, such metadata happens to exist in some nREPL namespaces, and some of my projects as well, so I presume that that's not the actual problem. Just out of curiosity, do things work well if you use e.g. inferior-lisp or ritz? Thanks for testing! - Chas On Feb 1, 2013, at 11:10 PM, Baishampayan Ghose wrote: Just did some testing with our code-base and Clojure 1.5.0-RC4 (with and without Chas' read-eval patch). There is definitely something strange going on. Things worked just fine with 1.5.0-RC4 but with the read-eval patch `lein swank` is completely broken but more than that, our code is failing to compile with this weird error - eval-reader: (clojure.lang.PersistentArrayMap/create {:author Joe Dev j...@helpshift.com, :doc Some doc here.}) RuntimeException EvalReader not allowed when *read-eval* is false. clojure.lang.Util.runtimeException (Util.java:219) Almost all our namespaces have documentation attached via metadata like this - (ns ^{:doc Some doc here. :author Joe Dev j...@helpshift.com} com.helpshift.some.ns (:require [com.helpshift.other.ns :as chon]) (:use clojure.test midje.sweet)) FWIW, the file that will fail to compile is random and I couldn't reproduce this error on a fresh project with just a couple of files. It's quite clear that the eval-reader is getting used from inside Clojure and we need to test out the edge cases a bit more. This is clearly not a low-impact fix, but IMHO we should take the time and get it right before 1.5.0 Regards, BG On Sat, Feb 2, 2013 at 4:01 AM, Chas Emerick c...@cemerick.com wrote: I have added a patch to CLJ-1153 that appears to address the *read-eval* problem: http://dev.clojure.org/jira/browse/CLJ-1153?focusedCommentId=30523#comment-30523 code on github: https://github.com/cemerick/clojure/commit/1f5c19c07443d2535ede4ff71d23b40c195d617f artifact on Clojars: [com.cemerick/clojure 1.5.0-SNAPSHOT] The Leiningen dependency above is 1.5.0-RC4 + the patch on the ticket. Note that you'll need to set your project's global :exclusions to [org.clojure/clojure] in order for the com.cemerick/clojure artifact to supersede it. It tests well for me, but needs to be exercised as much as possible. Some have already done so (there's an ongoing discussion on the clojure-dev ML with some initial test experiences: http://groups.google.com/group/clojure-dev/browse_frm/thread/cc6f747919db6c94), but I'm hoping that we can get as many eyes as possible on this — doing both testing as well as code/patch examination — so as to ensure correctness and maximize the chances of 1.5.0 final going out with this vulnerability buttoned up. Thanks, - Chas -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more
Re: *read-eval* vulnerability
One thing that hasn't been mentioned so far is that AOT-compiled classfiles generated using prior builds of Clojure will not load using a build of Clojure that includes a patch like this. Just something to consider for those of you taking the time to test, etc. - Chas -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: *read-eval* vulnerability
On Jan 31, 2013, at 8:03 PM, Chas Emerick wrote: On Jan 30, 2013, at 5:59 PM, Michał Marczyk wrote: On 30 January 2013 23:32, Chas Emerick c...@cemerick.com wrote: On Jan 30, 2013, at 12:23 PM, Michael Fogus wrote: RuntimeException EvalReader not allowed when *read-eval* is false. The problem is that the second eval gets (the actual + function 1 2 3) which invokes the right pathway triggering the exception. You can trigger the same exception by: (binding [*read-eval* false] (eval (list + 1 2 3))) Re-reading this, I'm clearly not grokking something here. Maybe I'm having a slow afternoon; send help. :-P This obviously ends up running through EvalReader — but why? How is LispReader ever involved at all? I believe the story goes like so: The eval call here compiles a list of a function object and three numbers. The function object gets compiled to code which effectively calls readString on #=(clojure.core$_PLUS_. ). (It so happens that print-dup knows how to handle functions; if it didn't, an exception would be thrown during compilation with the message Can't embed object in code, maybe print-dup not defined: ) When the compiled code is executed, readString gets called to reconstruct the function, and since *read-eval* is false, this fails. Whoo, sneaky. If only fns carried (most of) the metadata that their originating vars were defined with, print-dup would be able to emit a fully-qualified symbol instead of that bonkers ctor call...I think. This explains why my plan for a nuclear option for fixing *read-eval*'s default doesn't work when outside of a bare `java -cp ... clojure.main` REPL: https://gist.github.com/4674181 Much of the initialization of the nREPL / Leiningen / Reply toolchain involves evaluating code that's been prn'ed, and there may very well be a couple of nested `eval` usages lurking in there similar to what Fogus raised. So, getting *read-eval* to a safe default is going to require more than just setting its default to false; all usages of #= in https://github.com/clojure/clojure/blob/master/src/clj/clojure/core_print.clj need to be eliminated. Will be peeking at that next... It looks like print-dup is actually significantly relied upon by the compiler when emitting constants (e.g. keyword and symbol literals, namespaces, vars, etc) for generated classes. (There might be other usages that I haven't uncovered yet, but I don't *think* so.) I think that that print-dup usage will need to be replaced with corresponding asm method emits if we are to default *read-eval* to false without introducing eval-related limitations that will appear to nearly all users to be arbitrary and capricious. Per usual, I'm in over my head around compiler issues, but we'll see what next week brings. I suspect others that have done more compiler hacking than I would have an easier time of it... Cheers, - Chas -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: *read-eval* vulnerability
I have added a patch to CLJ-1153 that appears to address the *read-eval* problem: http://dev.clojure.org/jira/browse/CLJ-1153?focusedCommentId=30523#comment-30523 code on github: https://github.com/cemerick/clojure/commit/1f5c19c07443d2535ede4ff71d23b40c195d617f artifact on Clojars: [com.cemerick/clojure 1.5.0-SNAPSHOT] The Leiningen dependency above is 1.5.0-RC4 + the patch on the ticket. Note that you'll need to set your project's global :exclusions to [org.clojure/clojure] in order for the com.cemerick/clojure artifact to supersede it. It tests well for me, but needs to be exercised as much as possible. Some have already done so (there's an ongoing discussion on the clojure-dev ML with some initial test experiences: http://groups.google.com/group/clojure-dev/browse_frm/thread/cc6f747919db6c94), but I'm hoping that we can get as many eyes as possible on this — doing both testing as well as code/patch examination — so as to ensure correctness and maximize the chances of 1.5.0 final going out with this vulnerability buttoned up. Thanks, - Chas -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: *read-eval* vulnerability
Just did some testing with our code-base and Clojure 1.5.0-RC4 (with and without Chas' read-eval patch). There is definitely something strange going on. Things worked just fine with 1.5.0-RC4 but with the read-eval patch `lein swank` is completely broken but more than that, our code is failing to compile with this weird error - eval-reader: (clojure.lang.PersistentArrayMap/create {:author Joe Dev j...@helpshift.com, :doc Some doc here.}) RuntimeException EvalReader not allowed when *read-eval* is false. clojure.lang.Util.runtimeException (Util.java:219) Almost all our namespaces have documentation attached via metadata like this - (ns ^{:doc Some doc here. :author Joe Dev j...@helpshift.com} com.helpshift.some.ns (:require [com.helpshift.other.ns :as chon]) (:use clojure.test midje.sweet)) FWIW, the file that will fail to compile is random and I couldn't reproduce this error on a fresh project with just a couple of files. It's quite clear that the eval-reader is getting used from inside Clojure and we need to test out the edge cases a bit more. This is clearly not a low-impact fix, but IMHO we should take the time and get it right before 1.5.0 Regards, BG On Sat, Feb 2, 2013 at 4:01 AM, Chas Emerick c...@cemerick.com wrote: I have added a patch to CLJ-1153 that appears to address the *read-eval* problem: http://dev.clojure.org/jira/browse/CLJ-1153?focusedCommentId=30523#comment-30523 code on github: https://github.com/cemerick/clojure/commit/1f5c19c07443d2535ede4ff71d23b40c195d617f artifact on Clojars: [com.cemerick/clojure 1.5.0-SNAPSHOT] The Leiningen dependency above is 1.5.0-RC4 + the patch on the ticket. Note that you'll need to set your project's global :exclusions to [org.clojure/clojure] in order for the com.cemerick/clojure artifact to supersede it. It tests well for me, but needs to be exercised as much as possible. Some have already done so (there's an ongoing discussion on the clojure-dev ML with some initial test experiences: http://groups.google.com/group/clojure-dev/browse_frm/thread/cc6f747919db6c94), but I'm hoping that we can get as many eyes as possible on this — doing both testing as well as code/patch examination — so as to ensure correctness and maximize the chances of 1.5.0 final going out with this vulnerability buttoned up. Thanks, - Chas -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- Baishampayan Ghose b.ghose at gmail.com -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: *read-eval* vulnerability
On Jan 30, 2013, at 5:59 PM, Michał Marczyk wrote: On 30 January 2013 23:32, Chas Emerick c...@cemerick.com wrote: On Jan 30, 2013, at 12:23 PM, Michael Fogus wrote: RuntimeException EvalReader not allowed when *read-eval* is false. The problem is that the second eval gets (the actual + function 1 2 3) which invokes the right pathway triggering the exception. You can trigger the same exception by: (binding [*read-eval* false] (eval (list + 1 2 3))) Re-reading this, I'm clearly not grokking something here. Maybe I'm having a slow afternoon; send help. :-P This obviously ends up running through EvalReader — but why? How is LispReader ever involved at all? I believe the story goes like so: The eval call here compiles a list of a function object and three numbers. The function object gets compiled to code which effectively calls readString on #=(clojure.core$_PLUS_. ). (It so happens that print-dup knows how to handle functions; if it didn't, an exception would be thrown during compilation with the message Can't embed object in code, maybe print-dup not defined: ) When the compiled code is executed, readString gets called to reconstruct the function, and since *read-eval* is false, this fails. Whoo, sneaky. If only fns carried (most of) the metadata that their originating vars were defined with, print-dup would be able to emit a fully-qualified symbol instead of that bonkers ctor call...I think. This explains why my plan for a nuclear option for fixing *read-eval*'s default doesn't work when outside of a bare `java -cp ... clojure.main` REPL: https://gist.github.com/4674181 Much of the initialization of the nREPL / Leiningen / Reply toolchain involves evaluating code that's been prn'ed, and there may very well be a couple of nested `eval` usages lurking in there similar to what Fogus raised. So, getting *read-eval* to a safe default is going to require more than just setting its default to false; all usages of #= in https://github.com/clojure/clojure/blob/master/src/clj/clojure/core_print.clj need to be eliminated. Will be peeking at that next... - Chas -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: *read-eval* vulnerability
This isn't what you are asking, but I wanted to make a comment that there is a proposed patch to Clojure attached to ticket CLJ-904 that adds warnings to read and read-string about how their behavior depends upon the value of *read-eval*: http://dev.clojure.org/jira/browse/CLJ-904 Also, one of the examples for read on ClojureDocs.org defines a 'read-from-file-safely' function showing how to avoid eval behavior: http://clojuredocs.org/clojure_core/clojure.core/read Andy On Jan 29, 2013, at 11:02 PM, Takahiro Hozumi wrote: As more and more projects are using edn format for config, communication and etc, I think that default value of *read-eval*, which is true, is source of vulnerability such as recently reported ring issue [1]. And I don't understand why read-string depends on *read-eval* instead of argument. I believe optional argument is more preferable. What do you think? [1] Ring 1.0.3 / 1.1.7 released to fix security flaw https://groups.google.com/group/clojure/browse_thread/thread/7b0fe662867b9124 -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: *read-eval* vulnerability
This is exactly the thread that I meant to start a couple of weeks ago. Thanks for giving me the kick in the pants, Takahiro. :-) What brought the issue to the fore for me: * a greatly increased interest in security issues due to my own work's requirements * the most recent arbitrary code execution issues that the Rails community has had to weather * Building and maintaining Friend (http://github.com/cemerick/friend) has gradually brought me into contact with a handful of suitably experienced people that have done security reviews (none formal or published, BTW) of the Clojure web stack. In each of the three times I've been fortunate to discuss those reviews with their instigators, the first thing that comes up is *read-eval*. Perhaps not surprising — we've all known that its default is an open barn door. The sole thread I could dig up that discusses this is http://groups.google.com/group/clojure/browse_frm/thread/1bd6b66b51406ec9?tvc=1, where the common refrain is simply you should bind *read-eval* to false when reading data from unknown sources. Despite this not being news, recent events and certain changes in my foci have made it a newly-important issue, at least to me. Takahiro is exactly right that the growing usage of Clojure data / edn as a common serialization format for e.g. web service APIs makes the default of *read-eval* very, very relevant; IMO, despite any concerns re: breaking existing code. On that front, *read-eval* affects only the #= construction, a facility that is, IIRC, purposefully undocumented. This lack of documentation is good insofar as few people have used #=, but it has also left undocumented an implementation detail of the reader that ships with a dangerous default (see http://dev.clojure.org/jira/browse/CLJ-904). The advice and necessity to tighten up *read-eval* as good practice is a design fault. There are things that authors of certain key Clojure libraries can do to fix this up as a side effect of using those libraries, but it would obviously be ideal for Clojure/core to address the policy proactively. Otherwise, I'm certain that a time will come when people not steeped in Clojure arcana will be deploying vulnerable applications and services. Unfortunately, I suspect that time has long since arrived...we just don't (yet?) have the eyeballs and juice that the Rails community has to produce controversy. Cheers, - Chas On Jan 30, 2013, at 2:02 AM, Takahiro Hozumi wrote: As more and more projects are using edn format for config, communication and etc, I think that default value of *read-eval*, which is true, is source of vulnerability such as recently reported ring issue [1]. And I don't understand why read-string depends on *read-eval* instead of argument. I believe optional argument is more preferable. What do you think? [1] Ring 1.0.3 / 1.1.7 released to fix security flaw https://groups.google.com/group/clojure/browse_thread/thread/7b0fe662867b9124 -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: *read-eval* vulnerability
The most simple thing would be to change the default value of *read-eval* to false... Marek On Wednesday, January 30, 2013 8:02:54 AM UTC+1, Takahiro Hozumi wrote: As more and more projects are using edn format for config, communication and etc, I think that default value of *read-eval*, which is true, is source of vulnerability such as recently reported ring issue [1]. And I don't understand why read-string depends on *read-eval* instead of argument. I believe optional argument is more preferable. What do you think? [1] Ring 1.0.3 / 1.1.7 released to fix security flaw https://groups.google.com/group/clojure/browse_thread/thread/7b0fe662867b9124 -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: *read-eval* vulnerability
On Wed, Jan 30, 2013 at 10:18 AM, Marek Šrank markus.mas...@gmail.comwrote: The most simple thing would be to change the default value of *read-eval* to false... Understanding that this may break existing code (how much?), I think it would reflect well on the community to make decisions to improve safety and security, especially with respect to defaults like this. Avoiding surprises after deployment is a virtue in my option. +1 Regards, Kyle Burton -- Twitter: @kyleburton Github: https://github.com/kyleburton Blog: http://asymmetrical-view.com/ Fun: http://snapclean.me/ -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: *read-eval* vulnerability
I like the idea of setting the default to false. This potentially does break some code, but perhaps it breaks unknowingly insecure code - which is a pretty big bonus. I'd love it if I upgraded to a new release of Clojure and my app toppled down because of my own shortsightedness. An additional idea is to add an optional second argument to read-string, which does the binding for you. Regards, Paul On Wednesday, January 30, 2013 7:25:46 AM UTC-8, Kyle Burton wrote: On Wed, Jan 30, 2013 at 10:18 AM, Marek Šrank markus...@gmail.comjavascript: wrote: The most simple thing would be to change the default value of *read-eval* to false... Understanding that this may break existing code (how much?), I think it would reflect well on the community to make decisions to improve safety and security, especially with respect to defaults like this. Avoiding surprises after deployment is a virtue in my option. +1 Regards, Kyle Burton -- Twitter: @kyleburton Github: https://github.com/kyleburton Blog: http://asymmetrical-view.com/ Fun: http://snapclean.me/ -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: *read-eval* vulnerability
On Wed, Jan 30, 2013 at 1:02 AM, Takahiro Hozumi fat...@googlemail.comwrote: As more and more projects are using edn format for config, communication and etc, I think that default value of *read-eval*, which is true, is source of vulnerability such as recently reported ring issue [1]. Slight diversion here - what is the approved and safe way to read data from an untrusted source? I had a task this week which required data to to be read via an API. I wanted to use clojure data/EDN, and ended up with three primary issues: 1 - *read-eval*, which I bound to false 2 - data literals - I don't know which data literals are truly safe from an external source. I rebound *data-readers* to make sure only the system readers were around, which I assume are thought to be safe 3 - read-string only reads one expression, silently ignoring additional characters. I assume I could solve this using read and checking for additional items and raising an error if more expressions were received than expected In the end, I re-implemented this API using JSON, where there are no safety issues parsing data. This is an unfortunate decision, and I'd like to enable the clojure data version. I'm just not sure whether or not using read/read-string is intended to be a safe reader in the long term. If it's not, maybe we need a set of functions that are blessed for use with untrusted data? -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: *read-eval* vulnerability
Out of curiosity, I made a patch to Clojure that causes the default value of *read-eval* to be false instead of true, to see if any of the tests pass, and to let other people try it out in case it breaks things that would be surprising and/or disruptive. It is attached to this new ticket: http://dev.clojure.org/jira/browse/CLJ-1153 I found this behavior from one of the unit tests included with Clojure. Does it surprise anyone, or look like it would break something important? % java -cp clojure.jar clojure.main Clojure 1.5.0-master-SNAPSHOT user= '(list + 1 2 3) (list + 1 2 3) user= (eval '(list + 1 2 3)) (#core$_PLUS_ clojure.core$_PLUS_@11dfc8a0 1 2 3) user= (eval (eval '(list + 1 2 3))) RuntimeException EvalReader not allowed when *read-eval* is false. clojure.lang.Util.runtimeException (Util.java:219) The last expression evaluates to 6 when *read-eval* is true, with no exception. Andy On Jan 30, 2013, at 7:04 AM, Chas Emerick wrote: This is exactly the thread that I meant to start a couple of weeks ago. Thanks for giving me the kick in the pants, Takahiro. :-) What brought the issue to the fore for me: * a greatly increased interest in security issues due to my own work's requirements * the most recent arbitrary code execution issues that the Rails community has had to weather * Building and maintaining Friend (http://github.com/cemerick/friend) has gradually brought me into contact with a handful of suitably experienced people that have done security reviews (none formal or published, BTW) of the Clojure web stack. In each of the three times I've been fortunate to discuss those reviews with their instigators, the first thing that comes up is *read-eval*. Perhaps not surprising — we've all known that its default is an open barn door. The sole thread I could dig up that discusses this is http://groups.google.com/group/clojure/browse_frm/thread/1bd6b66b51406ec9?tvc=1, where the common refrain is simply you should bind *read-eval* to false when reading data from unknown sources. Despite this not being news, recent events and certain changes in my foci have made it a newly-important issue, at least to me. Takahiro is exactly right that the growing usage of Clojure data / edn as a common serialization format for e.g. web service APIs makes the default of *read-eval* very, very relevant; IMO, despite any concerns re: breaking existing code. On that front, *read-eval* affects only the #= construction, a facility that is, IIRC, purposefully undocumented. This lack of documentation is good insofar as few people have used #=, but it has also left undocumented an implementation detail of the reader that ships with a dangerous default (see http://dev.clojure.org/jira/browse/CLJ-904). The advice and necessity to tighten up *read-eval* as good practice is a design fault. There are things that authors of certain key Clojure libraries can do to fix this up as a side effect of using those libraries, but it would obviously be ideal for Clojure/core to address the policy proactively. Otherwise, I'm certain that a time will come when people not steeped in Clojure arcana will be deploying vulnerable applications and services. Unfortunately, I suspect that time has long since arrived...we just don't (yet?) have the eyeballs and juice that the Rails community has to produce controversy. Cheers, - Chas On Jan 30, 2013, at 2:02 AM, Takahiro Hozumi wrote: As more and more projects are using edn format for config, communication and etc, I think that default value of *read-eval*, which is true, is source of vulnerability such as recently reported ring issue [1]. And I don't understand why read-string depends on *read-eval* instead of argument. I believe optional argument is more preferable. What do you think? [1] Ring 1.0.3 / 1.1.7 released to fix security flaw https://groups.google.com/group/clojure/browse_thread/thread/7b0fe662867b9124 -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: *read-eval* vulnerability
RuntimeException EvalReader not allowed when *read-eval* is false. The problem is that the second eval gets (the actual + function 1 2 3) which invokes the right pathway triggering the exception. You can trigger the same exception by: (binding [*read-eval* false] (eval (list + 1 2 3))) People are not sending actual functions across the wire, so the only way to trigger this is to do some kind of pre-processing of symbols to functions or perhaps: (binding [*read-eval* false] (eval '(eval (quote (+ 1 2 3) ;;= 6 Whoops! Maybe setting *read-eval* to false is not enough. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: *read-eval* vulnerability
Although let me say that I agree with false being the default. I'm not saying that is a bad idea, only that we need to be careful if evaling what comes over... but I guess that is obvious and if not then we get what we deserve. ;-) On Wed, Jan 30, 2013 at 12:23 PM, Michael Fogus mefo...@gmail.com wrote: RuntimeException EvalReader not allowed when *read-eval* is false. The problem is that the second eval gets (the actual + function 1 2 3) which invokes the right pathway triggering the exception. You can trigger the same exception by: (binding [*read-eval* false] (eval (list + 1 2 3))) People are not sending actual functions across the wire, so the only way to trigger this is to do some kind of pre-processing of symbols to functions or perhaps: (binding [*read-eval* false] (eval '(eval (quote (+ 1 2 3) ;;= 6 Whoops! Maybe setting *read-eval* to false is not enough. -- -- http://blog.fogus.me -- http://github.com/fogus -- -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: *read-eval* vulnerability
Kyle R. Burton writes: Understanding that this may break existing code (how much?), I think it would reflect well on the community to make decisions to improve safety and security, especially with respect to defaults like this. Avoiding surprises after deployment is a virtue in my option. Considering that *read-eval* is undocumented, I think that makes for a much stronger case for changing its behaviour. Code that relies on *read-eval* defaulting to true is relying on an undocumented implementation detail, so breakage surrounding it should not be terribly surprising. If the default is not changed for whatever reason (which I believe would be a bad decision, but whatever) then at the very least it should be documented. Having a potential source of fatal exploits which can only be protected against by tribal knowledge is a really unfortunate situation. -Phil -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: *read-eval* vulnerability
I think the objective is to make read, read-string, etc. safe. Explicit use of eval is what it is...short of sandboxing, you're opting into all that eval implies. - Chas Michael Fogus mefo...@gmail.com wrote: RuntimeException EvalReader not allowed when *read-eval* is false. The problem is that the second eval gets (the actual + function 1 2 3) which invokes the right pathway triggering the exception. You can trigger the same exception by: (binding [*read-eval* false] (eval (list + 1 2 3))) People are not sending actual functions across the wire, so the only way to trigger this is to do some kind of pre-processing of symbols to functions or perhaps: (binding [*read-eval* false] (eval '(eval (quote (+ 1 2 3) ;;= 6 Whoops! Maybe setting *read-eval* to false is not enough. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: *read-eval* vulnerability
I would prefer that *read-eval* default to false. In this case, security is more important than backwards compatibility. However, I want to point out that there is an issue with backwards compatibility, especially for users of *print-dup* (default false). In many cases, with *print-dup* true, the printed representation will use the #= notation, which is readable only if *read-eval* is true. If your code is binding *print-dup*, you probably should be binding *read-eval* explicitly, not depending on the default. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: *read-eval* vulnerability
On Jan 30, 2013, at 12:23 PM, Michael Fogus wrote: RuntimeException EvalReader not allowed when *read-eval* is false. The problem is that the second eval gets (the actual + function 1 2 3) which invokes the right pathway triggering the exception. You can trigger the same exception by: (binding [*read-eval* false] (eval (list + 1 2 3))) Re-reading this, I'm clearly not grokking something here. Maybe I'm having a slow afternoon; send help. :-P This obviously ends up running through EvalReader — but why? How is LispReader ever involved at all? Thanks, - Chas -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: *read-eval* vulnerability
On 30 January 2013 23:32, Chas Emerick c...@cemerick.com wrote: On Jan 30, 2013, at 12:23 PM, Michael Fogus wrote: RuntimeException EvalReader not allowed when *read-eval* is false. The problem is that the second eval gets (the actual + function 1 2 3) which invokes the right pathway triggering the exception. You can trigger the same exception by: (binding [*read-eval* false] (eval (list + 1 2 3))) Re-reading this, I'm clearly not grokking something here. Maybe I'm having a slow afternoon; send help. :-P This obviously ends up running through EvalReader — but why? How is LispReader ever involved at all? I believe the story goes like so: The eval call here compiles a list of a function object and three numbers. The function object gets compiled to code which effectively calls readString on #=(clojure.core$_PLUS_. ). (It so happens that print-dup knows how to handle functions; if it didn't, an exception would be thrown during compilation with the message Can't embed object in code, maybe print-dup not defined: ) When the compiled code is executed, readString gets called to reconstruct the function, and since *read-eval* is false, this fails. +1 to setting *read-eval* to false by default, by the way. Cheers, Michał Thanks, - Chas -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: *read-eval* vulnerability
PS. The relevant part of Compiler.java is the emitValue method of ObjExpr (or grep for readStringMethod -- I believe this is its only use in the compiler). On 30 January 2013 23:59, Michał Marczyk michal.marc...@gmail.com wrote: On 30 January 2013 23:32, Chas Emerick c...@cemerick.com wrote: On Jan 30, 2013, at 12:23 PM, Michael Fogus wrote: RuntimeException EvalReader not allowed when *read-eval* is false. The problem is that the second eval gets (the actual + function 1 2 3) which invokes the right pathway triggering the exception. You can trigger the same exception by: (binding [*read-eval* false] (eval (list + 1 2 3))) Re-reading this, I'm clearly not grokking something here. Maybe I'm having a slow afternoon; send help. :-P This obviously ends up running through EvalReader — but why? How is LispReader ever involved at all? I believe the story goes like so: The eval call here compiles a list of a function object and three numbers. The function object gets compiled to code which effectively calls readString on #=(clojure.core$_PLUS_. ). (It so happens that print-dup knows how to handle functions; if it didn't, an exception would be thrown during compilation with the message Can't embed object in code, maybe print-dup not defined: ) When the compiled code is executed, readString gets called to reconstruct the function, and since *read-eval* is false, this fails. +1 to setting *read-eval* to false by default, by the way. Cheers, Michał Thanks, - Chas -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.