JRuby DSL encapsulation, exclude standard library - java

I'm trying to make a Java program that allows users to do some limited scripting with a Ruby DSL that I've written. The script the user writes is saved to a Proc object in JRuby. The problem arises in that the user can still access methods that are standard to Ruby, such as File.new, or creating classes, or basically messing with other internal logic of the program or computer.
Is there a way to limit the user's script to only the constraints of the DSL, using JRuby or Ruby or even Java? Or at least to remove the user's access to certain classes?

Since you're running under JRuby, you can use a Java security policy (policy file documentation) to prevent users from being able to do things like file or network I/O. Of course, this will keep your code from having those capabilities, too! You can whitelist code by jar URI or by jar signature, so one tactic is to create a "hull" of trusted code that strongly validates its input, package it in its own jar, trust it, and use it exclusively for your own code. Doing this right gets complicated fast (have an extensive test suite!), but it can be done.
To have explicit control over the namespace available to your DSL, you can use BasicObject. It doesn't mix in Kernel or any of the other things available in the standard Ruby namespace. This doesn't give you security, though, because users can still use ::File directly or include ::Kernel to get it all back!

Related

Can i stop the malicious reading the class files via "java.io" function,with NATIVE code(tool)?

we'd defend against the code crackers who can operate on the whole operation system who may read the encoded class-file via "java.io" and save the copy
we'd protect java-based application's intellectual property
this requirement was raised by several customers, so it has realistic value.
Simplex Java-JDK-JVM solution like securityManager without native code/tool can NOT be accepted because it's easy to be bypassed, since cracker have the admin privilege on the OS in this scenario.
You are probably better off using a SecurityManager to control access to Java APIs. The SecurityManager can call into native code if it wants.
Specifically, the checkRead method can be used to validate if a program is permitted to read from a given path, which covers not just FileInputStream.read() but any other means of reading files in Java.

Is there a way to block some parts of the Java Standard Library?

I am creating an application that allows people to load in their Java applications. Is there a way to disable parts of the Java Standard Library like JFrames and Files? Preferably when a user tries to access these parts it should throw an exception.
Preferably I would like to block the user to use any classes that do not do any I/O (like files and sockets) or do anything like rendering (JFrames).
The idea is the user can write Java plugins for an application, and thus doesn't need any of these options and should be prohibited from using them.

Set up permissions/features in desktop application?

i have a desktop application that consists of 10 features, and some clients asks only for 8 features or 7 features.
i want to have a way to manage adding/removing the permissions/features for the client (only i can control that). so that i can hide/show feature based on a flag.
is that should be done through a property file that contains the name of the feature with boolean flag, or what ?
please give me some ideas, thanks.
From your other answers, it sounds to me like the following additional details have cropped up; please let me know if I have these wrong:
You're delivering your application as a .jar file,
Each customer gets their build directly from you, and there's a small number of customers,
You configure a build specifically for each customer, and
You don't want your customers to be able to modify their feature access.
In that scenario, I'd store the "active" feature list in a hashed property value stored in a .properties file bound into the .jar. I'll describe one way to do that below. You generate the properties file just before delivery, add the file to the jar:
jar -uf applicationJarFile.jar configuration.properties
then sign the .jar and deliver it. At runtime, your app can load the properties file, run the hash of each feature, compare with the properties you've stored, and determine which ones are off or on.
Your properties, which determine which features are enabled, might consist of a list like this:
feature1=enabled
feature2=disabled
feature3=disabled
feature4=enabled
Write yourself a utility which hashes the whole string "feature1=enabled" plus a salt value, e.g. "feature1=enabledaKn087*h5^jbAS5yt". (There's code for this built into java; see How can I generate an MD5 hash?, for example.) The result will be an opaque 16-byte number, which you can then store in another properties file to be included in your app: feature1=1865834.... The salt value should be broken into multiple shorter strings in your code so your customer can't just retrieve it and easily duplicate the process themselves.
In your app, at startup, you construct the string above using both the "enabled" and the "disabled" value, run the MD5 of both, and compare it with the stored hash. That'll tell you what features to enable.
I think a separate .jar or .properties is a bad idea; it clutters your delivery.
You can automate the whole process fairly easily, since you can generate the properties on the fly any time, and bind them into your app.
You can add other "baked in" properties which gives you a lot of flexibility in the final deliverable, including things like skinning for customer branding.
As others have pointed out, though: there's lots of ways to approach this, depending on the rest of the details of your product and your overall goals. This is one way to do it, given the assumptions above. AFAIK, there's no "canonical" way to do this sort of thing.
You should consider using a License management api to do the same, which will give u both security and capability to change License pre/post installations.
It is not advisable to build adhoc licensing capabilty, take a look at License3j and TrueLicense, they are both free and can help you gain perspective or better fulfil your requirement
You could try and encode that in a file. I assume each user has an own installation/version of the application, right? I further assume the application should not need to check some web resource. Thus you need to implement that in a file.
However, you should encrypt that file and put the salt and key somewhere in the code where they can't easily be decompiled. Additionally create a hash to check for modifications of the file. That hash could be based on the application's size or something else.
Please note that there's no 100% security and any hacker could still crack your application. But in that case this would need some form of criminal energy not commonly present in the business world.
Modularize the application and deploy to each client only those parts that he wants/has access to. There's many ways to do it (the most complete but heavyweight being OSGi), but the specifics depend on your circumstances and requirements.
The quickest way to implement it might be to simply extract your extra functionality in separate JARs, and on deployment update the classpath appropriately.
It depends on the kind of application,kind of security you want and the number of people likely to use the application.
If the number of clients is not that big you can store their preference in some in memory data structure like a Map . Otherwise you can use file system or a DB depending upon the kind of security you want.
This is very open ended - it really depends on what you're trying to achieve, and what you mean by a feature.
One approach is to use a plugin based architecture. e.g. you have an interface
public interface Feature {}
and provide each of your ten features as implementors of this interface. Then have some method which runs at application start which looks for Feature subclasses on the classpath.
You can control which features a client has by including only the relevant features on the classpath, e.g. using maven.

How to evaluate user expressions in a sandbox

I want my app to evaluate an expression from an untrusted user, that I'll be reading from a JSON file. Such as:
value = "(getTime() == 60) AND isFoo('bar')"
I've found many threads about this here on StackOverflow. Usually recommending using Java's own ScriptEngine class, which can read JavaScript. Or recommending the user to either use an existing library such as JEXL, MVEL, or any other from this list:
http://java-source.net/open-source/expression-languages
But they all seem to rely on a trusted user (ex.: a configuration file you write yourself and want to do some scripting in it). But in my case, I want my expression evaluation to run in a secure sandbox. So the user cannot do something as simple as:
value = "while(true)" // or
value = "new java.io.File(\"R:/t.txt\").delete()" // this works on MVEL
And lock up my app, or access unwanted resources.
1) So are any of those existing libraries able to be easily configured so that it can run on a safe box? By 'easily', I mean high level configuration API that would faster for me to use than to write my own expression evaluator. After doing a little bit of my own research, both JEXL and MVEL seem to be out.
2) Or is there an existing expression language that is extremely simple so that it cannot be exploited by an untrusted user? All the ones I found are very complex, and implement things like loops, import statements etc. All I need is to parse math, logic operators and my own defined variables and methods. Anything beyond that is outside of my scope.
3) If the only solution is to write my own expression evaluator, then where can I find some guidance on how to write a consistent security model? I'm new to this, and have no idea of what are the common tricks used for code injection. Which is why I wanted avoid having to write this on my own.
I could recommend embedding Rhino, enabling the user to write javascript. It fits your criteria in (2) perfectly being a java library that enables you to run javascript (or run java from javascript).
You set up a context and the user only has access to what you put in the context or make accessible from it. The javascript expressions can be as simple as the simplest case you show above, or can get as complex as they need to. Embedding Rhino and exposing a limited set of objects was a great way to enable all sorts of user scripting in a past project and that was some years ago, Rhino is quite mature now.
You've also got the advantage that if your problem requires it, you may well be able to set it up so that the same expressions will happily run client or server side.
More information on embedding Rhino to accomplish what you need at http://www.mozilla.org/rhino/tutorial.html#runScript

how to bundle javascript files into Java application?

Javascript is executed by Java application. However, something like Jquery library is really too long to fit into a String variable. I am able to read jquery.js from a file but not sure how to package it inside the .jar file.
Loading the .js files is the same as loading any other resource from a jar file. Generally, this is what I do:
For files stored in the root of the jar file:
SomeClass.getClass().getClassLoader.getResourceAsStream( "myFile.js" );
For files stored along side a .class file in the jar:
SomeClass.getClass().getResourceAsStream( "myFile.js" )
Both techniques give you an InputStream. This can be turned into a String with code a little bit more work. See Read/convert an InputStream to a String.
This technique is for when your resource files are in the same jar as your java class files.
There are all sorts of places you can keep your JavaScript sources:
In the CLASSPATH. You fetch them with getResourceAsStream()
In the database. Yes, the database. You fetch them like you'd fetch any other CLOB.
Personally I've use both approaches for different purposes. You can keep your JavaScript files around in your build tree in a way that exactly parallels the way you keep .properties files. Personally I just keep them in with the .java files and then have a build rule to make sure they end up in the .war, but they can really live anywhere your build engine can find them.
The database is a nice place to keep scripts because it makes it much easier for your web application to support a "script portal" that allows dynamic updates. That's an extremely powerful facility to have, especially if you craft the web application so that Javascript modules control some of the more important business logic, because you can deploy updates more-or-less "live" without anything like a deployment operation.
One thing that helps a lot is to create some utility code to "wrap" whatever access path you're using to Javascript (that is, either the Sun "javax.script" stuff, or else the Rhino bindings; at this point in time, personally I'd go with straight Rhino because it really doesn't make much difference one way or the other anyway, and the Sun stuff is stuck with a fairly old and buggy Rhino version that in the current climate will probably not see an update for a while). With a utility wrapper, one of the most important things to do is make it possible for your JavaScript code (wherever it comes from) to import other JavaScript files from your server infrastructure. That way you can develop JavaScript tool libraries (or, of course, adapt open-source libraries) and have your business logic scripts import and use them.

Categories