Giter VIP home page Giter VIP logo

clojail's Introduction

Introduction

Welcome to the wonderful world of clojail! Clojail is a library for sandboxing Clojure code. Why is this useful? Well, for tons of reasons. I've personally used a sandbox for two different projects, such as Try Clojure and sexpbot. I've seen a wiki-like website where the pages were Clojure code evaluated in a sandbox.

One of the primary reasons for writing clojail is to replace clj-sandbox in my own personal projects. I'm also trying my best to make sure that it's useful for other people and their unpredictable needs as well. If you have any questions, ideas, or feedback, shoot me a message here on Github or in an email. Feedback of all kind is welcome!

Usage

You can get this library from clojars via cake or leiningen. The instructions are the same.

First, add [clojail "0.2.0-SNAPSHOT"] to your :dependencies in project.clj. After than, just run cake deps or lein deps if you use Leiningen.

Because clojail employs the JVM's built in sandboxing, you'll need to have a ~/.java.policy file to define permissions for your own code. If you don't do this, you'll get security exceptions. I've included a very liberal example.policy file that you can just copy over to ~/.java.policy.

Once you've got that set up, you can play with the sandbox. Let's create a sandbox:

(ns my.project
  (:use clojail.core)) ; Pull in the library.

(def tester #{'alter-var-root java.lang.Thread}) ; Create a blacklist.
(def sb (sandbox tester :timeout 5000))

You have just created a new sandbox. This sandbox will trigger whenever java.lang.Thread or alter-var-root is used in code. Anything else will pass the sandbox and be executed. Simple enough, right? Also, the :timeout bit is an optional argument. We've just lowered the timeout time to 5000 milliseconds, or 5 seconds. The default is 10000.

This sandbox isn't very secure. Let's create a new sandbox using the secure-tester in clojail.testers. This sandbox should be more secure. Can't promise total security however, since I can't test everything.

(ns my.project
  (:use [clojail core testers]))

; Don't bother with changing :timeout unless you want to. It was purely for demonstrational purposes.
(def sb (sandbox secure-tester))

Alright, cool. Now we have a supposedly secure sandbox. How do we use it? Simple! sb is now bound to a function that takes code and executes it in the sandbox.

(sb '(+ 3 3)) ; Returns 6
(sb '(def x)) ; Fails because def is not allowed in our sandbox.

Play around with it a bit.

(sb '(println "blah")) ; Returns nil

Wait... nil? It's doing the right thing and printing output to out and returning nil. However, for our purposes, maybe we want to get the output of sb as a string. Luckily, the sandbox accounts for that possibility and allows for you to provide, after the code to execute, a hashmap of vars to values. Here is how we can use that to get the output of sb as a string:

(let [writer (java.io.StringWriter.)] 
  (sb '(println "blah") {#'*out* writer}) (str writer)) ; Returns "blah\n"

There we go! Great!

Clojail can also create sandboxes based on a whitelist and a combination of whitelist and blacklist.

(def sb (sandbox {:whitelist #{'println '+}})) ; Creates a new sandbox based on a whitelist.

If you try to evaluate anything in the sandbox that isn't whitelisted, it'll go boom.

You can also supply a blacklist along with the whitelist.

(def sb (sandbox {:whitelist #{'println '+} :blacklist #{'println}}))

This sandbox whitelists println and then blacklists it, essentially doing absolutely nothing.

Well, that's about all folks. I hope my library is to your liking, and I hope it's useful in your own projects. Remember to not hesitate to give me feedback!

Testers

A tester is either a set of symbols, packages, and classes, in which case it's a blacklist, or it's a map with keys :whitelist and :blacklist (not necessarily both) bound to sets defining a blacklist and/or whitelist.

A nice feature of clojail is that you can blacklist (or whitelist) entire Java packages. Don't want anything in the java.lang.reflect package? Fine:

(use '[clojail.testers :only [p]])
(def reflect-blacklist #{(p "java.lang.reflect")})

Now you have a tester that will scream murder if someone tries to execute code using any classes from the reflect package.

Warning

We can't promise that clojail will be entirely secure at any given time. Clojail uses a blacklist-based sandbox by default, so there will almost always be little holes in the sandbox. Fortunately, that only applies to the Clojure side of things. Since clojail is backed up by the JVM sandbox, even if the Clojure sandbox is broken, I/O still can't be done. Even if clojail breaks, the breaker can't wipe your system.

What can happen?

If somebody finds a hole in your Clojure sandbox, all they can do is break the state of the sandbox. Meaning, if they find a way to use 'eval', they can eval any code they like. That code will still be evaluated under the JVM sandbox. They can, however, use eval to call def and redefine stuff in the sandbox. This also means they can cause out-of-memory errors by defining a bunch of stuff. You'll want to prepare for such things.

We're considering making an effort to maintain a tester in clojail.testers that tries to block out everything that's bad. The reason we haven't undertaken that task so far is because we don't want anybody to assume that the tester is totally secure, because you can never really be certain. secure-tester is unfortunately named. It should be secure-enough-tester or rather-secure-tester. For the most part, secure-tester is secure enough. Just be aware that there will be holes, just not catastrophic ones.

License

Clojail is licensed under the same thing that Clojure is. See LICENSE.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.