I'm working on a server app that may be extended by user-supplied Groovy scripts. It's evident that I want to make sure these scripts run in a very tight sandbox where they cannot disrupt the core application code or consume too much resources to overload the server.
I have studied various possibilities and the final solution may be a combination of these:
Run the script within a very restricted security manager. The script is run within a no permission SecurityManager. Additional permissions have to be declared (like Android).
Launch a new JVM. Create a ScriptProcess wrapper around Runtime.exec and spawning a new JVM with a security manager, limited heap, etc. Because we launch a full-blown process, we might get more control on monitor bad behaving ones? The cost in resource would be dire though... An alternative would be to use Ant here, but would it be scalable?
Java Monitor API In Java 6 there is a package with monitoring capacity. We could monitor threads and maybe detect infinite loops and memory consumption. Anyone used this?
These are what I have in mind today. What would be the best way to make sure these scripts behave correctly and still keep a certain scalability and performance?
An additional possibility is using Groovy 1.8 compilation customizers on the GroovyShell that runs the embedded scripts. You can pre-import classes and methods, restrict use of the Groovy AST, and pre-apply an AST transformation, such as #ThreadInterrupt, #TimedInterrupt, or #ConditionalInterrupt. Details at:
http://www.jroller.com/melix/entry/customizing_groovy_compilation_process
You should have a look at the project groovy-sandbox from kohsuke.
Have also a look to his blog post here on this topic and what is solution is addressing: sandboxing, but performance drawback.
Also have a look at the java-sandbox project and the accompanying blog post http://blog.datenwerke.net/2013/06/sandboxing-groovy-with-java-sandbox.html.
Related
My JEE app runs under tomee and allows the user to write his/her own scripts and run from a web gui, but I'd like to restrict certain operations such as System.exit(1) for example.
A discussion related to this issue can be found in the beanshell2 forum - check this out - http://code.google.com/p/beanshell2/issues/detail?id=15
Any scriptable language that works from within the JVM is OK, but I need this level of control. My first attempt was using beanshell, but it seems, as we can see from the discussion above, that this is not an option.
I would like to avoid more esoteric languages since the end user is technical, but I can't ask him/her to learn an unknown programming language just to write a script :-) [or maybe I can, if I don't find any useful option for this]
How can I get that? Groovy? Any other JVM-based script language maybe?
Groovy has a lot of power in CompilerConfiguration. You can choose the usable imports and a lot of other stuff. Allowed stuff can be whitelisted or blacklisted using SecureASTCustomizer
I used Rhino a long time ago. It allows run JavaScript into a Java App (or server side). You will probably need to manage security issues manually.
Not sure this is what you are looking for, but it can help: https://developer.mozilla.org/en-US/docs/Rhino
I have been wondering for a long time about converting Java projects to EXE.
The advantages relies in the faster deployment on Windows where the user simply double clicks the EXE and the application is launched where is with Java, he has to run certain commands.
But EXE is really not what the Java was intended for which is portability.
So what do you think, Java to EXE good or bad idea?
I found some interesting article here.
Update
Wow, so may contradicting views so far. I would like you guys to add the pros and cons of the JAVA to EXE.
Since my expertise is with Java Web Start, which is for launching desktop apps. with a GUI, please consider my advice to be targeted mostly at those types of apps.
Other people have commented on the OS specific nature of an EXE. I always have to wonder why people choose Java to develop Windows specific desktop apps., since the Visual Studio software for Windows would probably make both GUI development (no x-plat Java layouts to bend your head around) and deployment (just guessing it can produce an EXE) easier.
OTOH only you can say what is the best development tool/language for this use-case.
As to the potential disadvantages of creating an EXE, I note at the JavaFAQ on EXEs.
There are a number of good reasons not to package your application in an executable. Daniel Sjöblom notes:
It will probably not be any faster. Modern virtual machines don't interpret bytecodes, they actually employ a JIT compiler to produce native, compiled code. Check Sun's site for further information on JIT compilers.
Static compilation increases the size of your application multifold, since all of the libraries you are using need to be linked into the application.
You lose 'free' upgrades to your program. Anytime your user downloads a new faster virtual machine, your app gets a speed boost. If you are using an exe, you will not get this benefit.
Jon A. Cruz details some of the extra steps in the development process required to create an exe. He points out that developers making native exe's need to:
Validate the latest versions of the compilation product from the vendor. If critical bugs are found, it can't be used to build a shipping product until those are addressed. Work that needs to be done each time a revision comes out from the vendor.
Submit the software through a QA cycle. Once engineering thinks things are done, they need to be verified. So every shipping version and update of a product needs to go through complete testing cycles.
Further, since native compilation is per target platform, the QA cycle needs to be done completely for each target platform, which multiplies effort required.
Shelf space. Maybe not a big deal nowadays, but could be.
Then one needs to get all customers to upgrade to the proper version. Either have free updates (in which case the business needs to absorb the cost of producing updates) or alternatively needs to handle clients not all updating.
Jon notes futher: When you ship standard Java bytecodes, VM problems are the responsibility of the platform or VM vendor. However, when you ship compiled binaries, they become your responsibility (even if they're actually bugs in the vendor's compilation product).
...
Of course, my first choice for deploying Java rich client apps. is using Java Web Start. Putting some of the benefits/features of web-start in point form:
JWS provides many appealing features including, but not limited to:
splash screens
desktop integration
file associations
automatic update (including lazy downloads and programmatic control of updates)
partitioning of natives & other resource downloads by platform, architecture or Java version,
configuration of run-time environment (minimum J2SE version, run-time options, RAM etc.)
easy management of common resources using extensions
..
I decided to highlight auto-update since with the gradual shift from apps. delivered on disk to apps. delivered over a network, auto-update is becoming more common. JWS still provides the best update experience (very configurable, mostly transparent to the user) I've seen.
And of course, JWS works on OS' for desktop PCs for which Java is available.
Update
..does Java web apps require internet connection?
(Note that name is 'Java Web Start'.)
Sure it does. At least for the initial installation. Update checks can be specified to continue to launch the previously installed version of the app. if the user is not currently connected.
But then, (in my estimation) there are more machines (such as Netbooks) with no CD/DVD drive, than there are without internet connections. If you want to sell to the larger market, look to the network to deliver the app.
It depends on your needs. We had written a little barcode client scanner app here for our customer. They run it on two Windows-PCs. They are happy having their well-known exe-files. We coded it in Java and created an EXE-file for them.
Both parties are happy with it - so why not doing it?
When there are good reasons for it and nothing against it except dogmatism then it is ok in my opinion.
I am the author of the article you linked to - glad you've found it interesting!
As my article states, and as others have already pointed out in their answers, there are multiple ways to simplify deployment of Java apps - JNLP, EXE wrappers, installers bundling a private JRE, and so on. But true native compilation is the only option that also provides protection against Java decompilers - you simply do not ship the bytecodes.
Of course, that does not make reverse engineering of and tampering with your code impossible, just much more costly in terms of required skillset and time.
As far as application performance is concerned, native compilation can make a big difference if you target embedded systems. This also applies to memory and disk footprint, albeit to a smaller extent. On the desktop you would typically get better startup, but in most other scenarios and aspects the results would depend on your app.
If it has a good reason why not? Even Eclipse has an EXE on windows and (and platform dependent binaries for linux, mac, etc) Of course you loose portability but if that is not important then go ahead.
UPDATE
The question is what do you want to achieve by creating an exe :
Convenience : users on windows prefer to click on icons, this is especially true for the non geeks. On the other hand non geeks don't care what the link does internally if it starts up an exe or something else. You can have an application icon for non native Java applications too. The alternatives would be
Web start
Creating an installer package,e.g.: http://www.advancedinstaller.com/java.html This can also solve the problem of installing the JRE
Performance : If you compile your Java application into a native solution you may gain a bit on performance but it depends on what technology you use. For example Swing tends to be slow but compiling that to native is rather tricky. If you use SWT instead of Swing that is already using native components therefore no need for further native compilation. On the other hand recent JVMs perform very well and can compile java to native to further improve the performance bottlenecks. This is done silently on the background you dont need to worry about that.
Sum : in some cases it might be the only solution, but if you choose the right technologies there will be many Java based alternative solutions to reach the same goal.
The page behind the link in the question is written by a company that sells products that compile java to native code. I would not base a decision on that alone.
The question also says that the advantage of the exe a better user experience, because the user can just double click to launch the application.
That is possible with executable jar file. In fact, its actually quite easy with standard tools in the java runtime. You just have to add a manifest to a jar file, and specify the class with the main in it. You can also specify other jar files in the classpath relative to the location of the main jar file. You can also specify an image to use as a splash screen as a resource.
e.g.
Class-Path: lib/derby.jar lib/derbytools.jar lib/jcalendar-1.3.2.jar l
ib/joda-time-1.4.jar lib/log4j-1.2.14.jar lib/looks-2.2.1.jar lib/swi
ng-layout-1.0.jar
SplashScreen-Image: resources/splash.png
Main-Class: com.you.pkg.app.Main
The basic ant project in Netbeans will do all but the spash-screen for you if you use it. If your some reason you want to do all of that by hand, make sure you understand the format of the manifest file, its a bit finicky.
As Linux, mac., Solaris user I think this is bad idea.
If you want faster deploy on windows, just create installer.
Jar files provide many benefits including:
Compact: The whole application (i.e. all the class files) is stored in one archive file (which can incorporate image and sound files if required).
Ease of use: The application can be run by double-clicking.
Compression: The jar format allows you to compress your files for efficient storage.
Security: You can digitally sign the contents of a jar file. Users who recognise your signature can then optionally grant your software security privileges it wouldn't otherwise have.
I would not convert to exe.
Most Windows applications run from a .exe file (Word, Internet Explorer, FireFox, NetBeans, ...)
Java itself has no support for doing this as the executable file will then be platform dependent (i.e. it won’t run on Macs)
However, there are (free) applications that can do this for you.
Minecraft does it, so it must be a good idea!
All jokes aside, understand that it's not 'conversion' that you are looking for, but using a custom launcher. The article you linked does a nice job of explaining the different approaches and pros/cons of each. As a general idea, it requires the extra work of creating the launcher (and a different version for each different OS architecture), but it gives you a little more control (version checking is a nice feature, also you may update the application jar rather easily, like Minecraft does). Overall it's a good idea if you think it's worth the effort, and the (little) loss in portability.
Edit: the 'Custom Java Launchers And Wrappers' approach is the one that you should use if you don't need the really nifty extra features offered by those below it.
Depends on the user base. If they are tech-related in anyway then giving them a .jar file (which could be run by double click) is a good idea for mobility.
If your users are less techy but you still need it to run on multiple platforms then wrap it as exe for Windows and as .app for Mac.
Important: I would suggest making a script to wrap it into exe, so you run it each time you have a new version.
I want to create a Java-based website that will execute completely untrusted code from third parties. This third-party code will need to be able to access websites on the Internet, but not, for example, attempt a DoS on them.
I can choose the language, but if its obscure it will hurt adoption of the service I'm building.
Can anyone provide some pointers as to open source tools I should investigate?
Are you thinking of something like the Google App Engine? They do this for Java by providing a "sandbox" where the app has access only to carefully restricted subset of the Java API. You might take a look at their JRE White List for ideas. (They also provide other languages.)
Yahoo App Platform and Amazon Web Services provide similar functionality, but not in Java (which, from your tag, I assume is your main interest).
The key to do this with Java code, of course, is defining a SecurityManager and then carefully specifying the policy. Aside from that, you'd host on a Linux system and use a chroot jail -- or better yet, a chroot jail on a virtualized system.
You don't have to worry about someone using your single server to launch a DDOS attack, though, by definition!
First things first, you need to build an excellent jail or sandbox for your application. Virtualization can help, but even within a guest VM there are a lot of operations you wouldn't want your untrusted code to perform.
So investigate mandatory access control such as AppArmor, SElinux, TOMOYO, or SMACK. Any of these can lock down your server code to only a subset of allowed operations. There are patches available that can lock your application to a subset of system calls that is probably worth investigating as well. (Since I've worked on AppArmor for almost a decade, it's the tool I know best. It's also the tool I think best suited for the task, but SMACK's utter simplicity is really appealing.)
You can perform rate limiting at the firewall level to try to limit the amount of outside annoyances that your code hosting can cause. Rate limiting isn't the same as preventing :) but it gives you an opportunity to see obvious attempts to do stupid things in your logs.
Wait you all.
There is no reason for #sanity to look for 3rd party solutions, because Java already has a policy mechanism which allows untrusted code to access only a given subset of the Java API. See package java.security and SecurityManager. It allows you to say the JVM, "this app must have permission to access this stuff but not this other one".
But I think #sanity wants to grant a given permission to run untrusted code, without allowing it to do harmful things with that permission...
I'm not sure if I understand your question. But from what I understand you just need the user to be able to execute code (in a java-based website, however the code doesn't need to be java), in that case have you considered letting the user execute only client-side code (ie javascript)? This way the only machine they can harm is their own. You can read more about how other websites handle malicious code here and you can read about the few dangers of letting users execute JS here.
I do Java web development work using Spring MVC and basically I'm forced to do an Agile type of development where I have to make a lot of small changes and I sometimes end up wasting a lot of time having to compile each time I make a change ( I work for a start-up company and I am not given enough time to make unit tests, etc, this isn't ideal and I don't necessarily plan to stay with the company long-term but am just looking for ways to be more adaptable for the moment).
The app I'm working on needs to be fast and it does a lot of high volume data processing (its sort of a search engine but not a web search engine) so it has to be regular compiled Java for the production app but I'm wondering if I used Groovy with Grails, or something similar, for development if I could just write it as regular Java but then test code in real-time without having to recompile. I'm wondering how much effort would be involved in doing this as far as making it work then as compiled Java. Sorry if this is a newbie question I just am not sure where to look for info on this as most things about Grails seem more geared towards emulating scripting languages not what I am trying to use it for.
Agility is a state of mind, it doesn't have anything to do with a programming language or framework. I never have enough time NOT to do unit tests.
If you are coding in Java, code in Java, not in Groovy. Groovy is an (almost) superset of Java, so you could theoretically write your classes in Groovy and then compile them as Java, but this approach has a number of problems:
1) It's very easy to slip something in your code which isn't correct Java, closures are just SO useful :-)
2) Grails isn't easily translatable to Spring MVC, so you'd have to rewrite that bit as well.
So, I personally would not use Groovy/Grails.
When you say compile, do you really mean build the war and redeploy? Most IDEs (Eclipse, Intellij, etc) recompile a class as you save the file, so there is no delay. Assuming you're using such an IDE, you can run your (Tomcat) server from within Eclipse, and stuff gets automatically redeployed, and if necessary Tomcat restarts automatically.
If this still isn't fast enough, I recommend JRebel, which was so good that i forked out real money for a license. Using JRebel means that you (usually) don't even have to redeploy. You change a Java file in the IDE, and the change happens in your server without having to redeploy. I would highly recommend it.
One other thing I would do is to write unit tests for your code. You don't need to check them in, but they are a tool which will help your productivity.
What I would do here would be to embed groovy scripts within the java code as described here:
http://groovy.codehaus.org/Embedding+Groovy
In this way you can change your groovy code without the need to recompile. We've used this technique in our last legacy app that took 10-15 mins to recompile and install.
Groovy runs within the JVM and is dynamically compiled to bytecode, so there's no need to worry about the "production-ness" of it.
I have a situation where I need to execute some code that for a number of reasons (that I won't get into here) is better done in Java than in PL/SQL. As I see it there are two options:
Create a jar with all my compiled code and other supporting files/other jars, load the jar into Oracle (we're running 10g), and execute the Java from a stored procedure.
Pros: The Java code integrates very nicely with the rest of the system, can be called from existing PL/SQL.
Cons: I have very little experience with running Java in Oracle.
Leave the Java in a separate jar and execute it through shell scripts.
Pros: I've written Java like this before so I'm familiar with it.
Cons: Poor integration with everything else, will probably require extra manual steps to run and manage.
The Java code will have to read XML data from Oracle tables, and write data (non-XML) to other tables, so the amount of database integration made me think loading the Java code into the database might be a good idea but I'm just not sure...
What experiences do people have loading and running Java code from within Oracle? How easy is it to test and debug? Are there are any special tools required? Any "gotchas" I should be aware of?
I would go with option number 1: loading your java code in your database. I have had good experiences with this approach and you don't need that much experience to get a good solution working with this method.
The only part where embedding Java in your database gets complicated (you'll have to set special permissions for your Java code) is when you need access to external resources (network, file i/o to name a few) and it is clearly not your situation in this problem.
For your scenario, doing it within the database seems the right approach. Reasons to do it outside could be:
dependence on Java libs that are not compatible with Oracle's built-in JVM
need to run it under a different linux user account than Oracle's
but I don't see either in your scenario