POTD: Groovy Sandbox

April 29th, 2012

I posted the other day about Groovy’s SecureASTCustomizer and how it is harmful. In the end of that post, I suggested that doing the check dynamically would work better.

So in this installaition of “Project Of The Day”, I went ahead and implemented it. The result is Groovy sandbox.

My main idea is to confine the sandboxed script into its local object graph. The script should be allowed to mutate this graph all it wants, but it’ll be only allowed to include objects of known whitelisted “safe” types (such as String, List, Date etc.), and a few known safe instances, which acts as a bridge between the sandbox and the rest of the world. These bridge objects would have to be written carefully.

To use this, you have to add SandboxTransformer to your CompilerConfiguration first:

def cc = new CompilerConfiguration()
cc.addCompilationCustomizers(new SecureTransformer())
def binding = new Binding();
binding.robot = robot = new Robot();
def sh = new GroovyShell(binding,cc)

And now any script compiled via the resulting shell object will be sandboxed.

When a sandboxed script executes, all of the following operations are intercepted.

  • static/instance method invocation foo.bar(....)
  • object allocation new Foo(...)
  • property access and assignment zot=foo.bar / foo.bar=zot
  • attributes access and assignment zot=foo.@bar / foo.@bar=zot
  • array access and assignment zot=foo[bar] / foo[bar]=zot

To examine those calls and reject some of them, create your own implementation of GroovyInterceptor and registers it to the thread before you start executing the script:

def sandbox = new RobotSandbox()
sandbox.register()
try {
    sh.evaluate("robot.leftArm.move()")  // this is allowed to complete
    sh.evaluate("robot.selfDestruct()")  // no!
} finally {
    sandbox.unregister()
}

See the robot example for a complete example.

Now let’s see if I can get some feedback from real Groovy experts, and see if they’d be willing to take this into Groovy itself…

potd , ,

Groovy SecureASTCustomizer is harmful

April 27th, 2012

I was looking at Groovy DSL slides from Guillaume Laforge when I noticed about SecureASTCustomizer, which led me to what appers to be the original introduction post from Cedric.

Being able to lock Groovy execution down would enable me to use Groovy in more places, so I did a bit of experiment. But I regrettably have to conclude that this feature is practically unusable. In fact I’d argue that it is actively harmful, as it gives a programmer a false comfort.

The fundamental problem is that Groovy is a dynamic language, yet SecureASTCustomizer works by looking at Groovy AST statically. So it’s very easy for Maloney, a malicious attacker, to bypass many of the checks. For example, Cedric’s post talks about how it can let you blacklist/whitelist classes that can be imported. Well, the actual goal of the programmer is to prevent the class from getting used, and not to get them imported. And sure enough, even if I white list the importable classes to java.lang.Math, Maloney can still do Math.class.forName('some.secret.class') to get a reference to a Class, and therefore render the import restrictions pointless.

Then I thought about disabling access to the getClass() method. But this doesn’t work well either because Groovy allows 5."class" and 5["class"] to access properties. To statically prevent this, you’d have to prohibit the array access and a string literal, but that doesn’t leave much of a language!

Many other checks offered by SecureASTCustomizer are equally useless. For example, there’s receiversClassesWhiteList that’s supposed to let you restrict the methods the script can invoke by whitelisting the declaring class of the method. But once again, this is a static check! Groovy compiler doesn’t work very hard to infer types, so much so that it can’t even guess that x=="foo" is a boolean type. Therefore, if you actually try using receiver whitelisting, pretty quickly you’ll discover that you either have to allow Object as a receiver (because Groovy assigns this to every expression when it couldn’t infer the type), which will basically renders the point of whitelisting moot as you can now invoke any method by simply casting the expression to Object.

If you go the other route and disallow Object as a receiver. That will reject almost all non-trivial scripts. Or I suppose you can prohibit a method call, but that doesn’t leave much of a language, does it.

Like I said, I think this is fundamentally a futile approach. You just can’t perform any meaningful static sandboxing on a dynamic language.

Instead, what I think is more fruitful is a dynamic checking. For example, what if the compile-time AST transformation intercepts every method call and property access? That is, transform z=x.y as z=checkedGet(x,"y"), transform x.y=5 into checkedSet(x,"y",5), and finally transform o.foo(a,b,c) into checkedCall(o,"foo",[a,b,c]). This does make execution a whole lot slower, but I can now perform meaningful checks. And unlike Java SecurityManager, this is a lot more friendly to libraries and web applications, who cannot take over the entire JVM.

I haven’t actually put together such an AST transformer, but this doesn’t look too hard.

What do people think?

Uncategorized , ,

COM4J updates

April 27th, 2012

It’s been a while, but I’ve posted a new version of COM4J. COM4J is a library that lets you talk to Windows COM components. Unlike similar libraries lika jacob, which makes you feel like you are working with reflection, COM4J is designed to work with type-safe annotated interfaces, which makes you feel like you are working with Java libraries. COM4J is also built on top of vtable invocation, not on IDispatch, so it can work with components without the dual interface support (boy those words bring back memories!)

I use this library in Jenkins, among other places, to provide a better native integration.

The major change in this version is that it finally has 64bit Java support. The original work was contributed in 2011, but I’ve never cut a release out of it officially. It contains a number of bug fixes, additional conversions support. The code is now on GitHub, and the website is moved to here.

Uncategorized , , ,

The Butler’s Service: Promotion for Jenkins User Conference in Paris

April 4th, 2012

We have just increased our enrollment capacity for the Jenkins User Conference (JUC) Paris, to be held on April 17th. The enthusiastic response to our first-ever Paris JUC has been terrific – and we want to get everyone there! The learning, networking and connecting that occurs within the Jenkins community at JUC is great to see. I saw it in spades last fall in San Francisco and it was terrific. I want every Jenkins user who is able to experience JUC to do so.

Since Mr. Jenkins, our iconic butler, and I are traveling to every JUC conference this year – all six of them – we have worked up a little scheme, with the folks from our sponsor CloudBees, to get YOU there, too.

Here is the deal. Jenkins and I are offering a special Butler’s Service promotion for JUC Paris. Ticket prices recently increased to the full conference price of €206, from a previously discounted rate of €104. The registration fee is needed to cover the cost of the conference, but we realize this can get in the way of people trying to attend. As a compromise, on this Thursday and Friday, 5-6 April, we will reduce the ticket price to the lower advance registration special pricing that was in effect. So on Thursday and Friday, you can still register for JUC Paris at the lower €104 price. (For anyone who paid the full conference price, we will refund the difference.)

Let Your Friends and Colleagues Know About This Special Offer!

To experience what JUC is like, watch the highlights video from our San Francisco conference. It will give you a feel for the quality of our speakers, the learning – and, yes, the fun that went on!

We have a lot to share with you on April 17. In addition to all of the great sessions we are offering, you’ll get to see many developers of the plugins you’ve been using (some of whom even I haven’t met before in person!), and there will be some exciting updates and other news to share about our favorite continuous integration platform. You will want to be there to hear and see it all, first hand.

I hope to see you on April 17 in Paris – be sure to sign up by end-of-day, Friday, and take advantage of this great deal served up by the Butler!

jenkins , ,

Debian and Maven, a crash of culture

March 16th, 2012

Tim O’Brien posted his frustration about the state of Java packaging in Debian. While I’m not affiliated with Debian nor Ubuntu, I wanted to post something in defense.

I completely understand where Tim is coming from. To the eyes of Java developers, the Java packaging in Debian looks completely Sisyphean. We got all the binaries and their dependencies captured in a machine readable form (aka POM). Can’t we just take them as-is, do a bit of metadata conversion, and make all those artifacts available to the Debian world so that we can just have a single package manager on Debian? If that’s your line of reasoning, you are in for a surprise, because Debian wouldn’t like that.

The reason they don’t do it is well summarized in the Debian Social Contract. It’s the equivalent of the U.S. Constitution for the Debian project — everything they do derive from this. Binary jars are bad for Debian because they don’t give the users the freedom to modify them and create derivative works. Debian is not just a means to let you conveniently install all the programs you need. It’s a pursuit of certain kinds of freedom.

In that sense, it’s somewhat like the “Free Software” movement. They both have some pretty strong guiding principles, and at times, for outsiders they look like they are “wasting” their efforts or being impractical. But the thing is, it’s those guiding principles that attract so many people to the effort, and that’s what keeps the project going and produce all the incredible good stuff that we use everyday. Criticizing them for their principles while you enjoy the benefits of the very same principles feel bit single-handed to me.

I think a better way forward is to write a little program that takes the source jar (which most jars in the Maven central should already have) and the POM, then generate a build script that simply compiles the source jar into the binary jar. The said program should also inspect the jar file to figure out any resource files, and treat them as source files. That way, we can machine-generate Debian source packages. Granted, not all source packages produced that way would pass the requirements of the Debian Freesoftware Guideline, but I bet substantial number of Maven artifacts are simple enough that this will be actually completely satisfactory. And then humans can concentrate on harder ones.

Anyone interested in giving that a shot?

Uncategorized , , ,

Come join us on “Selenium, Jenkins, Robots, Oh My!” tomorrow

March 13th, 2012

I’ll be speaking tomorrow at San Francisco Selenium Meetup about Jenkins & Selenium — mainly recent improvements in the Selenium plugin, as well as several other new plugins relevant in the combination of Jenkins and Selenium, complete with a demo. I’ve got a couple of pet-peeves against the Selenium project, so I’m going to pitch them there to see the reaction, too.

I’ve told that Jason Huggins from Sauce Lab is going to pick up where he left off in the last Jenkins User Conference to talk about his robot, and Theo Cincotta from Eventbrite will give the case study of how Eventbrite uses Jenkins & Selenium together internally, so the whole thing should be a great mix of fun & useful topics, all packed in a Wednesday night from 6:30pm to 8:00pm, with beer and food.

The event is free, but you do need to RSVP, instead of the usual RSVP in the SF Selenium meetup group page at meetup.com (which currently says 209 people coming, when the EventBrite RSVP page says the capacity is 100 people — so I need to check with the organizers to make sure they know what they are expecting…)

jenkins , , ,

Attaching files to JUnit tests

March 13th, 2012

Despite the fact that it is the de-facto standard of test reports in any programming languages (perhaps except .NET), JUnit test report format has a number of problems. One is that the format isn’t explicitly defined (and I’ll discuss this in a separate post), but another problem, which I’m going to dedicate this post for, is the lack of attachment support.

It is often very conveniet to be able to attach arbitrary files to a test report. Imagine Selenium tests capturing screenshots. Or JavaEE tests that deploy webapps, then you want to capture server log files. Or if you are doing UI automation testing, how about a video recording that your screen automation framework has produced?

Today, doing this mostly requires that you (as a test author) write some files somewhere, then print out that file name to stdout/stderr. This works for humans who are looking at the output, but not for CI servers like Jenkins. So I hereby propose a bit of convention to decorate this current practice, to make those files discoverable by Jenkins.

For this, I’ve improved the JUnit attachments plugin to recognize the following format. It has to occupy a whole line.

[[ATTACHMENT|<absolute file name>]]
[[ATTACHMENT|<absolute file name>|{ ... additional metadata in JSON ... }]]

The additional metadata isn’t currently used, but I intended it to describe what the attached file means. For example, if your test always attach a couple of log files, it’d be useful to describe which file is which, so that CI servers or test report tools can display them as such. Or metadata for human readable display name would be useful, as these attachment file names are often cryptic just to make them unique.

When you run these tests from within Jenkins, these files are then picked up and stored by Jenkins, and the test report page will include them as links.

Ideally, the test report format should be expanded to cover things like this, but unfortunately I think that’d require too much collaboration between too many people to the point that it’s unrealistic — if we are to do that, test frameworks like JUnit first needs to offer this as API methods for listeners, then the test drivers like Ant/Maven needs to be expanded to honor those when they produce test reports. Then finally we can improve the CI servers.

I’ve been patiently waiting for that to happen for long time, but it’s just not happening. So instead, I’m taking the matter into my own hands, and came up with this convention.

Convention like this is useful only if enough people uses it. So I hope you’ll like this. If you think this convention can be improved, please let me know.

jenkins , ,

POTD: Package renamed ASM

March 3rd, 2012

Today’s project of the day is a package renamed ASM library.

I previously wrote about a problem in otherwise quite useful ObjectWeb ASM library. Namely, it breaks backward compatibility in such a way that badly breaks apps/libraries that use them. In that post, I wrote about two proposals to fix the pain point. One is to include debug information, which has been fixed starting 3.x. But the other package renaming hasn’t been addressed in the last 2 years.

This has been in the back of my head, but it never came high enough until recently I had another NoSuchMethodError caused by ASM3. One of the servlet containers shipped ASM3 and it broke Jenkins that bundles ASM2. Between this and ASM4 release for JavaSE 7, which will likely gain popularity over time, I finally decided to fix this problem once and for all, in a way that everyone else can reuse.

The solution, as explained in the original post, is to put each major ASM version in its unique package name. I pakage-renamed ASM2 in org.kohsuke.asm2, ASM3 in org.kohsuke.asm3, and ASM4 in org.kohsuke.asm4. The package name only contains the major version because I trust the ASM developers to maintain compatibility between minor releases (and I believe they’ve maintained this thus far.)

These artifacts are available in org.kohsuke:asm2:2.2.3, org.kohsuke:asm3:3.3.0, and org.kohsuke:asm4:4.0 — these are packaged renamed by jarjar and I tested them somewhat to make sure it’s not downright broken.

If library A depends on asm2 and library B depends on asm3, and someone else uses both A and B, everything will work fine because asm2 and asm3 are in the different pcakages. If A depends on one version of asm3 and B depends on another version of asm3, then the transitive dependency resolution will pick up the newer version and both will work (or you end up implicitly picking up one version over another, and you don’t enjoy the latest bug fixes, but at least it won’t die with LinkageError.)

When you search “asm3″ in Maven central, you see a large number of renamed ASM3 in various projects. Hopefully that madness will stop now!

The other interesting thing about this effort is that I’ve used Gradle to package rename them. Lately I’ve been using Gradle for publishing transformed artifacts like these to a Maven repository, and I like it a lot. But more about that in another post.

potd, Uncategorized

POTD: checking package name for Windows reserved words

March 1st, 2012

Today’s project of the day is a little tool that checks problems in your package names that can bite you on Windows.

For backward compatibility with MS-DOS (which had ended its life more than 15 years ago!), Windows doesn’t allow you to create files/directories of certain names, such as “AUX” or “PRN” (see Microsoft Knowledge Base.)

This can bite those of us who develop on Unix — when you accidentally create a file or a directory of this name (say in the package name), it’ll be all right for you, but your colleagues who use Windows will not be able to build them. Worse yet, if none of your colleagues use Windows either, this problem can get unnoticed until you ship/test the code.

So I wrote a little tool that proactively checks for this problem. It’s an annotation processor that kicks in automatically, so you just need to add it in your classpath when you compile your source files. If you use a build system that can handle transitive dependencies (such as Gradle or Maven), you just need to use it in one of your libraries, and all the code that uses your library also benefits from this check.

My hats off to Microsoft for their rigorous commitment to the backward compatibility, and just one more reason why you should be always testing your Java program on multiple platforms…

potd , ,

Jenkins User Conferences 2012

February 28th, 2012

As a result of the success of the Jenkins User Conference last year in San Francisco, this year CloudBees and other sponsors are planning 4 Jenkins User Conferences around the world. Yup, that’s right — four!

Making events like these successful would be a win for everyone, so I’d like to encourage you to …:

Register to attend

If you are in the greater Paris or NY City metro areas, sign up now! You will experience lots of great learning opportunities and further your Jenkins knowledge. And perhaps more importantly, you’ll get the chance to connect with other Jenkins users and learn about the latest developments in the Jenkins project. I always love watching the community interact – we all learn from each other and on so many occasions, I have seen a Jenkins user have an “Aha!” moment in conversation with another Jenkins user. There’s something magical about meeting face-to-facet that you just can’t replace any other way.

Dates for the JUC conferences in the first half of 2012 are:

  • Paris — April 17: Early Bird discounted registration (€50) ends 18 February

  • New York City — May 17: Early Bird discounted registration ($54) ends 25 February

  • Registration includes all sessions, lunch, a social/networking hour at the end of the day and a FREE Jenkins t-shirt (a hot commodity at the JUC last October)

  • Two more conferences will be scheduled later in the year in San Francisco(Sept) and Antwerp (Nov), and there’s a planning going on for one in Tokyo — stay tuned for dates.
Apply to speak

Share your Jenkins knowledge with the community. The quality of the speakers was the most highly praised aspect of JUC 2011. If you’ve been writing plugins, tell the community what those are and meet people who use your plugins, which is quite a rewarding experience. If you’ve been using Jenkins in interesting ways, tell the community about it, and through the feedback you’ll learn just as much as they would. Do it fast though — the deadline for Paris is February 24th and for New York is March 16th.

Sign up to sponsor

If you can, consider sponsoring the events. If you feel your organization has benefitted from Jenkins, now’s your chance to give back to the community… and at the same time get some great visibility for your company.

 

If you still need more convincing about JUC, watch the highlights video from last year’s conference. Looking forward to seeing you!

jenkins ,