Is it sufficient to secure a Java web application with the rights of the user that is running the application server process or is it reasonable also to use SecurityManager with a suitable policy file?
I have used to do the former and not the latter, but some customers would like us to also use SecurityManager that would explicitly give permissions to every third-party component to be sure there isn't any evil code lurking there.
I've seen some Servlet containers, like Resin to propose not using SecurityManager to slow things up. Any thoughts?
While I hate to ever recommend not using a security feature, it's my opinion that a SecurityManager is more intended to manage situations where untrusted or third-party code is executing in the JVM. Think applets, or a hosted, shared app server scenario. If you have complete control over the app server and are not running anybody else's code, I think it's redundant. Enable the SecurityManager does have significant performance impact in my experience.
There is no simple yes/no answer to your question, because it really depends: what do you want to secure, and what do you want to secure it from?
For example, I've used SecurityManager to implement IP filtering and allow only whitelisted IP addresses to connect to my application. If you just want to disallow access to disk files, maybe running application as user with lesser privileges is better solution.
If you don't trust third party plugins at all, remember that once you allow execution of plugin code, that plugin can crash your application if it wants to even if you use SecurityManager. If your application loads plugins, maybe whitelisting plugin and checking the list before loading plugin is better solution.
If you decide to use it, you will take a performance hit (since JVM will do more checks), but how fast it will run really depends on your code/configuration that will do the checks. My IP whitelist was pretty fast since it included only single list lookup; if your checks include invoking remote web service and accessing database you can slow things down a lot, but on the other hand, even that should not matter if you have enough hardware and few concurrent users (in other words, if you can afford it).
Correctly configurin Security Manager in java can be hard. For instance, if you do not restrict the security manager itself, one can bypass all security just by setting the Security Manager to null.
Using a security manager only makes sense if your JVM will run untrusted code, otherwise it is a pain to set up, because you'll have to know beforehand what permissions you should set for each feature (ex: RMI, sockets, I/O) and for each client.
Related
Did anybody run Apache Sling with an enabled Java SecurityManager? That'd need a special java.policy file to allow the actions done by all deployed bundles, and it'd be extremely helpful to have a basic version that already allows what's needed by the bundles provided with the basic Sling Starter, and to which one could add policies for additional deployed code.
I'd also be interested if someone can tell that employing the SecurityManager is infeasible in a Sling setting, perhaps due to its design properties (such as the ability to add JSPs to the JCR at runtime).
Background: If you run code of several mandants on one server, that might be neccessary to separate their code from each other. While OSGI does have some mechanisms to separate bundles from each other, it'd be trivial for malicious code to use e.g. Java reflection to grab internal stuff from services provided by other bundles. An enabled security manager might at least make that much more difficult.
(I do realize that even with a security manager it's probably quite possible for malicious code to use bugs and design flaws to get access to resources of other users on the system, and that probably the only way to seriously separate code from different mandants would be using different servers. But at least one can try to make it hard.)
I'm interested in using JMX to monitor/configure a simple Java Client/Server application. For example, we would capture any network exceptions that occur in a Java program.
Can MBeans be extended in this way? Or are they limited to more concrete get & set functions?
So far, I've looked in Notifications and Monitor MBeans
Thanks
Well I would say that it's definitely doable. I was using JMX in an Apache Wicket application earlier with custom MBeans. Anyway MBeans is just a wrapper around some logic in your server application. So you can take the data directly from your application.
If you want to take an example how is this done in a working application you might want to checkout this:
https://github.com/apache/wicket/blob/master/wicket-jmx/src/main/java/org/apache/wicket/jmx/wrapper/MarkupSettings.java
The class basically holds a reference to the application and asks for data directly form the server app.
When the server starts up, then it registers all the MBeans through an initializer class:
https://github.com/apache/wicket/blob/master/wicket-jmx/src/main/java/org/apache/wicket/jmx/Initializer.java
Then every time when you take a look in your MBean server you will see the latest up-to-date information coming directly from the app.
There are some caveats though. One caveat is that Java in general doesn't provide any good abstraction to capture all Exceptions of a given type coming from any source of the application. You can register your catch-all exception handler but as far as I can remember it doesn't work perfectly.
What I was doing when I had to do something like this, I was using AspectJ to register an all catch place to handle exceptions. I was using compile time weaving to reduce the performance implication but I am not sure how much does it affect the overall performance (if it affects at all).
¯\_(ツ)_/¯
The other caveat is that JMX connections are usually difficult to set up in an enterprise environment. If you have to log-in through two hops just to arrive to the production servers because there are firewalls everywhere than your monitoring connection will definitely fail and you need to keep buying beer to your sysadmin and convince your manager that this is not imposing any security risk. :)
There is one thing though. You say
to monitor/configure a simple Java Client/Server application
You want to configure / monitor the clients as well? I've never done that. I am not sure that's even possible.
I'm writing a JavaFX2 application that accepts arbitrary code to be loaded from remote locations. For me using a custom SecurityManager, ClassLoader and ProtectionDomain was the way to go. Unfortunately this seems to be the same setup that's used to sandbox applets, which has caused a lot of security exploits and that in turn has persuaded people to fear Java Web Plugin and removing it from their OS entirely.
Is Java sandbox a secure environment to run untrusted code onto, or is it just the Java Web Plugin as a whole to be insecure?
The security manager provides your app. with exactly as much protection as it provided the plug-in. Which was, given the security bugs, 'not much'.
It currently plugs the known security bugs (AFAIU). But as in any complex plug-in there are probably more, yet to be discovered, or possibly to be introduced in new versions or new APIs.
So basically, your code should go somewhat beyond a standard security manager, black-listing entire packages and (if need be) providing utility methods through which to perform activity normally handled by that package.
But then, that advice is the first point of a 20+ point list that I might be able to name 2 or 3 of the possible things an app. might need to guard against, in running untrusted code. Though that is not the question..
Is Java sandbox a secure environment to run untrusted code onto..
No. Java security might provide a good starting point for security against untrusted code, but it would need to be expanded specific to the app., and have other elements in order to be suited to the task required. Even then, there are the 'unknown security bugs' (in both the JRE as well as your own security efforts) to consider.
I always seem to have this internal struggle when it comes to user interface. I build up an application "engine" and tend to defer user interface to after I get my algorithms working. Then I go back and forth trying to decide how to let a user interact with my program. Personally, I'm a fan of the command line, but I can't expect that of my users generally.
I really like what's possible in the browser in the age of web 2.0 and ajax. On the other hand it's not so hard to make a Swing front-end either, and you can generally count on a more consistent presentation to the user (though using a good javascript framework like YUI or jQuery goes a long way toward normalizing browsers).
Clearly both approaches have their merits and drawbacks. So, what criteria / parameters / situations should lead me to use a lightweight (e.g. web-based) GUI? What criteria / parameters / situations should lead me to use a heavier (e.g. Swing-based) GUI?
It is not my intent to start a flame war, merely interested in the community's constructive/objective opinions.
Edit #1
In light of the first few responses, I would like to clarify that I would like to deploy my application regardless, not host it on some internet server necessarily. So I would have to deploy with a light-weight web-server infrastructure a la Jetty/Tomcat or similar.
It depends on the application and this is essentially a usability driven question (though there are considerations like data storage and platform requirements). Think of the pros and cons.
Pros of a lightweight Web UI:
Ease of distribution
Platform independent
Ease of maintenance
Cons of a lightweight Web UI:
Less environmental control
Markup standards vary between browsers
Requires a web server and everything that goes with it
Pros of an executable UI
More environmental control (i.e.: full screen applications, etc)
Not necessarily subject to latency and outages
Cons of an executable UI
Pushing updates may be more difficult
Requires installation
Potential platform requirements (frameworks, packages, etc)
Potentially requires knowledge of advanced networking topics (web services, etc)
One small factor you may want to consider is that the user will have go through some type of installation (albeit minimal) if you distribute a swing application.
Also a web application will allow you to accurately track the usage of your application (via google analytics or something similar). Not sure if that's a concern but it may be useful to you in the future.
If it is a client-server application I would normally go for a web frontend for the application.
You will save yourself of countless problems with things like installed JRE versions, distributing upgrades, application permissions, disappeared shortcuts...
You need to break the requirements of the application down to decide this...
Do the users have Java of sufficient version installed? It will need to be, to run a Swing GUI.
Do you have a web server?
Do you need the flexibility of a Swing GUI or the accessibility of the web interface?
Is Java Webstart and option, if so, you can distribute a Swing GUI via the web.
Does your application perform extensive calculations or processing? If so, a client app may be the answer.
There are a million questions such as these. I would suggest a brain storming session and keeping track of all the pros and cons of each, adding a point score, than throwing it all away and going with your gut feeling :)
If you anticipate there being frequent updates to the app then web based may be better since the user would not have to update the client or install a new client containing the updates.
If you think that the user may need the ability to use the app while not conencted to the internet then swing would be better.
Just two things off the top of my head.
Think about the users and use cases of your project.
Do users expect to have access to it when they're disconnected from the Internet (for example, on an airplane or in a coffee shop with no Internet access)? Use Swing.
Do you want users to be able to access the same tool from different computers (for example, both at work and at home)? Use a web UI.
Also consider whether the user needs to save and load data, and whether the tool produces data files that some might consider sensitive (if so, storage on the web might be an issue).
Do make a quick guess I often try to ask myself/customers if the application has a high "write" demand.
For a mostly read-only application a thin-client solution is perfectly well suited.
But if a lot write actions are needed then a swing desktop application has more flexibility.
Personally I always prever a swing desktop application. It can easily deployed using Java Webstart.
Not knowing anything about your application I can not give the best recommendation possible. However I can state from personal/professional experience that installing an application on clients machines is a LOT more of a pain in the ass than it seems.
With AJAX/web you really only have to worry about supporting like three browsers. Installation messes/updates are only felt once when you deploy the product to the web server.
With like a stand-along Swing app, you get to deal with the really really big mess that is installing the application onto unknown systems. This mess was so bad that things like AJAX were really pushed along to make web apps behave/feel like a real native app.
I'm writing a web application that is supposed to run on Tomcat on Ubuntu. On Ubuntu, Tomcat is per default configured to run with the Java SecurityManager. Besides my own web application, there will only be some well known third party web applications related to my own, like the BIRT report engine.
If one of the web applications fails or gets compromised, it may take down all the others without harm, because they all belong together. What I don't wont to happen is that a compromised web app compromises the system itself, like calling rm -r /
Do I need to use the java security manager to achieve this? Or is it only necessary to protect one web app from the other? I'd really like to prevent the effort to create .policy files for all the 3rd party web applications I intend to use.
In theory yes. But I've heard that people run into stacks of problems when they try to "lock down" server side code using the security manager. Applications are frequently not designed with this in mind, and you spend a lot of time debugging SecurityExceptions until you get all of the permissions settings right.
EDIT:
I suggest that is simpler to run two Tomcat instances to avoid the problem of one application doing something that will bring down everything in a single Tomcat. (For example, fill up the heap, leak file descriptors or ... call System.exit().)
If you still are worried about an application "breaking out" of Java and doing the equivalent of "rm /*", then you could run each Tomcat instance in a separate "chroot jail" or a virtual host. Or you could simply run Tomcat from a restricted user account and make sure that the account cannot access / update files that it should not.
Avoiding a "rm -r /" doesn't require a security manager. It is sufficient if the user that runs the Tomcat process has limited access (i.e. doesn't have write access to / or any other important area).
SecurityManager is just another layer of security you can apply to Tomcat and, depending your application, can be very difficult and time consuming to get right. As you've already noted, getting this right for third party applications and libraries can be even more difficult.
In my opinion, configuring this in any detail is the last thing you should be considering.
Much of this has been said already here, but if I were you, I'd follow these steps, in order:
Run Tomcat using jsvc under an account with the least possible privelages (by convention an account named 'tomcat', 'tomcat6' etc.). If you've installed the Ubuntu package, the init script it installed already does this, so if you start tomcat via this script, you're covered.
For more on jsvc, see http://tomcat.apache.org/tomcat-6.0-doc/setup.html
Run jsvc using chroot. Limit what's in the virtual filesystem you specify with chroot to only what Tomcat needs.
Secure your Tomcat, database and OS configuration. The Center for Information Security has good baseline guidance for this - http://cisecurity.org/en-us/?route=downloads.multiform.
Application security. This is most important, but 1., 2. and 3. are so easily achieved by comparison that I suggest you do those before this (or better, in parallel). Ensure all input to your application is validated before it is used. Use something like OWASP's Enterprise Security API as a starting point - http://www.owasp.org/index.php/Category:OWASP_Enterprise_Security_API. Everything else you do is a failsafe for your application security efforts. If your application is insecure, the machine it's running on may remain secure because of the other steps you've taken (low privilege account, chroot, secure config etc.) but the data that the application manages will be compromised.
Security Manager. Once you're happy that you have a good baseline of application security, by all means consider adding a security policy to your ongoing application security efforts.
Other things you can do include running an IDS like Snort on the machine to detect some intrusion attempts, running a file watcher like swatch to detect unexpected file modifications (especially to configuration files) and running various log analysers to attempt detect any other attempts at intrusion.
There's always a tradeoff to be made with any security effort. You can never totally secure your application and there always comes a point when further effort just isn't worth it. A full blown security manager configuration, for most people, falls into this category.
"Do I need to use the java security manager to achieve this [compromising the system itself]?"
No. There are easier ways (low privilege account, chroot, secure config etc.)