Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does the variable *read-eval* do?

Tags:

clojure

I cam across this code from a remoting function (clojurescriptone) where the data sent back from the browser is being read. My question is what is the significance of setting the read-eval to false is ?

(binding [read-eval false] (read-string data))

Thanks, Murtaza

like image 797
murtaza52 Avatar asked Sep 09 '12 09:09

murtaza52


2 Answers

It is a security measure so the browser cannot send code to be executed in the server. For example if the client/browser send "#=(eval (System/exit 1))" and *read-eval* is true, the server process will exit, which is probably something that you don't want.

See the difference of behaviour:

(binding [*read-eval* false] (read-string "#=(eval (System/exit 1))"))
(binding [*read-eval* true] (read-string "#=(eval (System/exit 1))"))

Also see the docs on *read-eval*.

like image 86
DanLebrero Avatar answered Oct 03 '22 16:10

DanLebrero


The main purpose of *read-eval* is to allow the reader to evaluate an expression at read time, typically for something that doesn't have a literal notation. If *read-eval* is true (the default), read and read-string will evaluate the expression following #=. You can see how that feature is used when *print-dup* is bound to true -- meaning that you want values to print in a way that their precise types are preserved, in which case you'll see some values print with #= notation. The default for *print-dup* is false -- for most things the standard Clojure notation is fine. For example, we don't normally care about the distinction between Integers and Longs.

The *read-eval* feature is useful for loading code, but it creates a security risk when used with untrusted input. The usual advise before Clojure 1.5 was to bind *read-eval* false when dealing with user input. However, there were still some issues with reading Java objects that might cause problems. That's fixed in Clojure 1.5. More importantly, Clojure 1.5 introduced, clojure.edn/read and clojure.edn/read-string which do not support any of the *read-eval* features. They're safe for reading user input representing the usual Clojure values as defined by the EDN format. See http://edn-format.org for more information.

like image 43
miner49r Avatar answered Oct 03 '22 15:10

miner49r