radioAe6rt

Tomcat “-security” option and catalina.policy file

with 11 comments

Newcomers to the Tomcat -security option may find this useful.

The objective: modifying the catalina.policy file to allow your webapp just enough leeway to run – and no more.

Warning: modifying my catalina.policy file to allow a simple webapp that uses Apache XML-RPC3 and Hibernate took me one full day to figure out. Not in theory, but in practice (well, ok, some theory). Using -security represents hours of hard work, especially if this is your first encounter with the policy file. The webapp itself may look simple, but getting the rules right for the app may not be, especially when using sophisticated layers like Hibernate. I performed all the tweaking of the policy file by trial and error. There may be a better way, but I learned a lot in this approach.

So, off we go.

Enable just enough debugging in Tomcat by setting the environment variable

export CATALINA_OPTS=-Djava.security.debug=access,failure

and start Tomcat with the security option

sh bin/startup.sh -security

which assumes you are in CATALINA_HOME. Begin monitoring catalina.out for security violations.

Realize that if your application calls some codebase that requires a permission then both your app codebase and the other codebase need the permission granted, not just the other codebase. All codebases along the call chain need the permission.

After you run the webapp, search catalina.out for instances of “denied“. This will reveal which heretofore un-granted permission was requested, with any optional parameters. For example, access: access denied (java.util.PropertyPermission entityExpansionLimit read).

Then seek a few lines forward for “domain that failed ProtectionDomain” for the codebase or domain broke the rule. For example, access: domain that failed ProtectionDomain (file:/u/p/tomcat/shared/lib/dom4j-1.6.1.jar

Without the debugging, catalina.out shows you the java.security.AccessControlException with some broken rule detail, but it will not always show you much in the way of specifically which code domain needed the access.

Other tips:

Take advantage of wildcards in permissions, such as permission java.util.PropertyPermission "log4j.*", "read,write";

Take advantage of the file-naming rules.

Update

Here is catscan, a perl-based tool I wrote to generate a fine-grained catalina.policy file. The input is catalina.out with the access,failure flags set, as described above.

Usage: catscan accrued.policy

then append the accrued output to the default catalina.policy file. It is important not to remove or zero-out catalina.out during this process, because it holds accrued state you need to generate the right rules.

Note that for this to be a useful, you will still find yourself starting and stopping the app a number of times. Reason being is that some access violations bring the servlet startup process to a halt. So you must add the new rule by running the utility on every newly produced catalina.out file, the restart the container. Repeat to catch the next set of violations. Still not an ideal situation.

No surprises, but here is a sample accrued policy rule set. It needs optimizing, but seeing these rules at such a fine grain is quite interesting.

What would be very helpful, in retrospect, is to have an option you can pass to the JVM that would tell you which security constraints were violated, but otherwise behave as if the -security option were not set. Then, you could capture the access violation warnings in one runtime session. Sort of like “make -n“: show me what would have been done without actually doing it.

[tags]tomcat security,catalina.policy,java.security.AccessControlException[/tags]

Written by radioae6rt

May 7, 2006 at 9:31 am

Posted in Internet

11 Responses

Subscribe to comments with RSS.

  1. What would be REALLY nice would be some sort of callback on either violations or all permission checks, which would allow you to do anything with the info.

    (eg write a “learning” mode for your application, or a GUI to let users click away their security :-)

    Anyhow, thanks for the blog, it’s been on my todo list to try to do something like this for, well, years I guess.

    grh

    May 10, 2006 at 12:50 pm

  2. Yes, a callback would be very useful, too. Anything to help build at least a starting point version of the file without resorting to sweeping grants of the form “$codebaseprefix/-”.

    I built the first version of the policy file by hand, and fatigue sets in so quickly that I just gave up and starting using wildcards and recursive file notations with abandon.

    Thanks for the feedback!

    Mark

    ae6rt

    May 10, 2006 at 1:04 pm

  3. you said

    “What would be very helpful, in retrospect, is to have an option you can pass to the JVM that would tell you which security constraints were violated, but otherwise behave as if the -security option were not set. ”

    So you could write a security manager that delegated to another security manager. Your security manager would catch SecurityExceptions from the other, log them (or call a listener or whatever) and then just return.

    I don’t think it would be too hard to wire in (tho that’s not my area of expertise).

    Bruce

    May 10, 2006 at 3:51 pm

  4. Very cool idea.

    ae6rt

    May 10, 2006 at 4:00 pm

  5. Another option would be to use JChains (http://www.jchains.org/ and open sourced ad https://jchains.dev.java.net/). It will allow you to see the permissions required for your application and produce a template policy file. Sort of what the perl tool you found does.

    I did something similar for some external web applications that had to run under a Resin host, and it can become a bit tricky, as you need to give permissions to the container’s classes, access to temporary directories… So good article.

    S!

    GreenEyed

    May 11, 2006 at 3:16 am

  6. Thank you for the pointer!

    ae6rt

    May 11, 2006 at 3:32 am

  7. It’s not very difficult to write a delegating security manager that logs checks and failures (I wrote and use one at work). Just remember to check for your delegate’s codebase as a ProtectionDomain: I seem to remember some recursion problems if I didn’t.

    Benjamin

    May 11, 2006 at 7:06 am

  8. Without revealing any company secrets, can you perhaps point us to an example of such a delegating security manager?

    Thanks.

    ae6rt

    May 11, 2006 at 11:03 am

  9. I like this idea but if there are multiple webapps running on the same web server? Don’t the security managers have a conflict in this case?

    sma

    February 22, 2007 at 10:03 am

  10. Hi, sma, and thanks for the feedback. I’ve never considered the case where the profiler would serve more than one webapp in the same container. But yes, I would think that if two webapps shared the same VM, they would both be subject to the single security policy.

    This idea has come a long way since this blog post, and based on an idea “Benjamin” above planted, and encouragement from friends, I wrote this article for OnJava:

    http://www.onjava.com/pub/a/onjava/2007/01/03/discovering-java-security-requirements.html

    Mark

    ae6rt

    February 23, 2007 at 4:44 pm

  11. Thank you so much for the explanation and your catscan perl script. I have been searching around why my web app was running on Windows and not Ubuntu => it’s only a matter of policy (Tomcat on Ubuntu is much more secured)

    ch4mp

    September 25, 2007 at 2:15 am


Leave a Reply