Reputation: 13514
I have an application where Clojure code is evaluated either from the application classpath or as a remote file store resource.
Only the administrator has access to the classpath location, but all users can provide their code on the remote store. In order to facilitate some operations, the application API includes a auth/as-admin
macro that executes the input forms if they were executed as a logged in administrator, but obviously I don't want it to be successfully used in user provided code.
How can I reliably restrict the use of auth/as-admin
to classpath-only code, preventing any "malicious" binding
in user code trying to circumvent the constraint?
Upvotes: 3
Views: 176
Reputation: 91577
hiredman maintains the clojurebot on the clojure IRC channel. this bot is a great example of how to sandbox clojure code from untrusted sources.
https://github.com/hiredman/clojurebot
Thanks Hiredman! Clojurebot it awesome :)
Upvotes: 1
Reputation: 49339
After reading the code and before evaluating it, you can iterate it and remove dangerous calls,
(ns tmp
(:require [clojure.zip :as zip])
(:use clojure.contrib.pprint))
;;stolen from http://nakkaya.com/2011/06/29/ferret-an-experimental-clojure-compiler/
(defn remove-form [tree pred]
(loop [loc (zip/seq-zip tree)]
(if (zip/end? loc)
(zip/root loc)
(recur
(zip/next
(if (pred (zip/node loc))
(zip/remove loc)
loc))))))
(remove-form (read-string (str \( "(+ 1 1)
(println \"No print\")"
\)))
#(and (seq? %)
(= 'println (first %))))
this will remove all println calls,
tmp=> ((+ 1 1))
or you can use a library such as clj-sandbox that is designed for this.
Upvotes: 2