skuro
skuro

Reputation: 13514

Restrict the use of a Clojure fn

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

Answers (2)

Arthur Ulfeldt
Arthur Ulfeldt

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

Hamza Yerlikaya
Hamza Yerlikaya

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

Related Questions