On Tue, Sep 22, 2009 at 6:46 PM, Eric Tschetter <eched...@gmail.com> wrote:

> If I do just
>
> curl 'http://localhost:43034/1.0/cloj' -H 'content-type:
> application/clojure' -d '(json-str {:howdy ["hi" 1 2 3]})'
>
> I get this exception
>
> java.lang.Exception: Unable to resolve symbol: json-str in this
> context (NO_SOURCE_FILE:0)
>

Looks like only clojure.core is imported as far as read/eval is concerned.

Something like this
>
> curl -v 'http://localhost:43034/1.0/cloj' -H 'content-type:
> application/clojure' -d "(require 'clojure.contrib.json.write)
> (json-str {:howdy [\"hi\" 1 2 3]})"
>
> Doesn't work because I'm only read/eval'ing one thing.
>

Wrap the require and json-str in a do.

Or, modify your original code so that what read operates on includes this
require. Something like:

(defroutes evallerificator
 (POST "/1.0/cloj"
   (eval (list
             `do
             `(require (quote clojure.contrib.json.write))
             (read (PushbackReader. (InputStreamReader. (request
:body)))))))
 (GET "/"
   (html [:h1 "Hello World"]))
 (ANY "*" (page-not-found)))

or, if that doesn't work (it proves to be "read" that does symbol
resolution),

(defroutes evallerificator
 (POST "/1.0/cloj"
   (eval (read-str (str
                      "(do (require 'clojure.contrib.json.write) "
                      (slurp (PushbackReader. (InputStreamReader. (request
:body))))
                      ")"))))
 (GET "/"
   (html [:h1 "Hello World"]))
 (ANY "*" (page-not-found)))

(untested!)

But, this looks like a gaping security hole. You're taking an HTTP POST
request body and eval'ing it. Someone will, sooner or later, try typing
"(delete all the secret files)" into the web form and clicking Send. Or
worse, something that will actually delete something or grant privilege.
Sending "(doall (iterate inc 1))" will crash the server with OOME after a
lengthy 100%-cpu-use hang while it fills memory with consecutive Integer
objects, for a cheap and easy DoS attack. And so forth.

The last example shows that even vetting the incoming string for I/O is not
enough protection. (And the incoming string could sneak I/O in in numerous
ways; a lengthy computation could assemble a dynamic string equal to
"with-open" or "InputStream" and another equal to a file path ("/etc/passwd"
anyone?) and combine them. It might use "symbol" or "read", then "eval".
Blocking eval just makes them resort to cobbling together classnames and
method names from obfuscated fragments and then invoking Java reflection,
e.g. Class/forName. Maybe if you blocked every Java reflection-related class
name as well as read, eval, and the Clojure I/O forms -- but even then
someone can request an infinite seq be doall'd or similarly to cause some
amount of trouble, even if deleting files or creating a privileged account
on the server machine is placed out of their reach.)

--~--~---------~--~----~------------~-------~--~----~
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
-~----------~----~----~----~------~----~------~--~---

Reply via email to