Following symbolic links in Tomcat

We have several web applications derived from the same code base and as well as sharing the jars in WEB-INF/lib, we provide set of administration pages to allow users to configure and administer the applications. Until now, we’ve always had to make copies of the admin pages and this has caused us configuration headaches as we try and make sure that all the applications have the latest versions of all the pages.

But now I’ve finally managed to work out how to make Tomcat follow symbolic links—and it’s very easy! All you have to do is add allowLinking="true" to the Context tag in the context.xml file. For Tomcat 5.5 and later, I find the most convenient way is to have a META-INF directory in the web application directory and have a context.xml file in this. Like this all the files to do with the web application are in the same place and copying and deploying is easy. So, my context.xml looks like:

<?xml version="1.0" encoding="UTF-8"?>
<Context path="/myapp" allowLinking="true">

As soon as you restart Tomcat, the change comes into effect and you can share directories between applications or even link to directories outside the web application home directory. If you still using Tomcat 4.x then you can’t use the context.xml in the META-INF directory. Instead you have to put it in the server.xml itself.

18 thoughts on “Following symbolic links in Tomcat”

  1. It turns out that there are a few caveats to using “allowLinking”. First the documentation for the context element for Tomcat 5.5 says: NOTE: This flag MUST NOT be set to true on the Windows platform (or any other OS which does not have a case sensitive filesystem), as it will disable case sensitivity checks, allowing JSP source code disclosure, among other security problems.

    And second, in the migration documentation from 5.5 to Tomcat 6, it says “When using a shared webhosting environment, it is recommended that usage of context.xml inside a WAR is forbidden (using the deployXML attribute of the Host element)”. Presumably this is because it would allow badly behaved configurations to be loaded?

    So, just be aware of these pieces of advice if you are going to use the context.xml and allowLinking.

  2. Hi,

    Just wanted to thank you both for the info on the allowLinking setting.

    We run Australia’s largest/oldest java hosting company and have a customer on a dedicated server who write and operate
    a CMS.

    Usually all their sites run under a single account, but they wanted a way to have a separate account (separate Host entry)
    which uses the WEB-INF, META-INF and data folder from their main CMS account.

    The purpose was so that their client could log in using FTP and create additional folders of static content.

    We found at first that we could symlink META-INF with no problems, but symlinking WEB-INF ended up deploying an
    application with no name (which did not correctly start up). The other alternative was to copy the WEB-INF folder
    into the new webapps_someclient/ROOT folder, but this meant that any code updates needed to be deployed to
    every Host set up in this way.

    After adding the allowLinking flag however, it all works fine.

    As an added benefit, the FTP service has not been set to follow symlinks, so their client can now log in, see the
    META-INF, WEB-INF and data folder links, but cannot change-directory to them, and therefore cannot download
    or edit the application classes.

    Also – good advice by DenisH. This setup is on Linux so does not affect the security.

    We recommend the use of context.xml as it’s the most effective way of allowing customers to upload their applications,
    either unpacked or in a WAR. Other alternatives are placing context files in the conf folder, which limits what customers
    can do, or in server.xml (yuck).

    One recommendation I have however, is to remove path=”/myapp” from your Context tag. It is unnecessary and may
    cause headaches if you relocate the application. If you leave it out, the path defaults to whatever the application
    path is relative to the webapps folder.

    /webapps/ROOT – the META-INF/context.xml for this app will default to “/”
    /webapps/myApp – the META-INF/context.xml for this app will default to “/myApp”

    … so leave the path attribute out, then you can copy myApp to myOtherApp and the application will still work properly
    without any modifications to it’s context.xml file.

    The context.xml file is also a great place for JNDI DBCP datasource settings, and Tomcat Realms security file/database location


  3. Hi All,

    Using “allowLinking=true” in context.xml of tomcat 6, I am able to access soft links, within the application project directory.
    but the problem is when I undeploy the application by deleting only project.war file, tomcat is deleting all the contents inside the soft links along with that project directory, but for me it’s causing the serious problem by deleting the valuable web content.

    Let me know if you have any clue on this.


  4. Hi,

    following on from this,

    have a simple virtual host with a context element inside, simple one line

    symlinks work fine on one level, so my app directory is x, everything is served from x including symlinks to physical directories or files.

    however if a symlink under x points to another symlink which then points to a physical directory, i get a resource not found error.

    this is the same behaviour for all tomcats 5.5 + works fine in tomcat 5.019/28
    any ideas would be much appreciated


  5. I tried to get the symbolic link working on my tomcat 6.0.20
    in my context.xml file i only have this line

    The context.xml is located in:

    any one an idea why this is not working


    1. the line is ( see above)

      context allowLinking=”true”

      i cannot use the real line, id did that but it wil not display here

    2. Hi Sprokkie,

      You’d have to give us a bit more info. Do you know if it’s finding the context.xml file? (You could check this by setting some other property and then checking to see if it is set, have a look at to give you ideas of what you could change.)

      Then next try pointing at a directory that isn’t symbolic and check that works, then if it does, change it to the symbolic link and see if it stops working.

      You should probably ensure there aren’t any other context.xml files that take priority over the one you’re setting up. Again, check the link above as it explains the order that Tomcat uses to find these.

      Good luck!

      1. I did a “file find” on context.xml
        I found 3 file’s in each file i added the allowLinking=true line.

        i run mango on this tomcat server.

        Other folders are accesable.
        i made a folder called test and put a file in that folder
        it was accesable with the browser.
        The folder that is the symbolic link is not accesable

        What could i try more ?

        1. Right, if you have 3 context.xml files, you need to be careful to see which one is being used. I wouldn’t modify all of them. I would be tempted to rename them out of the way one at a time until you find it doesn’t work any more. (If you find it does still work, have a look in server.xml and other config files in case there are even more references to your app).

          Once you’ve found the appropriate context.xml, you can add allowLinking=”true” and test before and after to see if there is any difference. If you put a symbolic link to a file inside the test folder that works, does link work there? That’s how I use it. I have a bunch of applications that all share the same admin pages, so I have a symbolic link to the admin directory which is outside each of the individual apps.

  6. I made a symbolic link in the test folder to a file.
    It still did not work. 🙁

    The server.xml is very complicated,
    I addes the line with allowlinking to another file it is called
    aplicationcontect.xml then the aplication did not work anymore

    i ran out of context.xml file’s ….

  7. Sorry, I’m running out of ideas. Is there any chance you could set up a vanilla installation of Tomcat 6 somewhere else and create a brand new single app and then step by step ensure you’ve got a context.xml file for the new app, then add allowLinking, then add a link? That would check that your version of Tomcat does support it and that you’re setting up the symbolic link correctly?

    Other than that, I don’t know what to suggest 🙁

  8. What about webapps that use struts and/or spring? These do not have a traditional layout, i.e. there will not be a single context.xml file to modify…

  9. Just so you know, you can do this for all webapps by editing the context.xml in /etc/tomcat6/ (in Ubuntu)

    <!– The contents of this file will be loaded for each web application –>

    … more stuff here …

  10. If you use Embedded Tomcat 8, without web.xml and other stuff, then the quick way to accomplish this solution in code is the following:

    Tomcat tomcat = new Tomcat();
    StandardContext ctx =
    (StandardContext) tomcat.addContext("/", new File(SRC_WEBAPP).getAbsolutePath());

    File additionWebInfClasses = new File("target/classes");
    WebResourceRoot resources = new StandardRoot(ctx);
    resources.addPreResources(new DirResourceSet(resources, "/WEB-INF/classes",
    additionWebInfClasses.getAbsolutePath(), "/"));
    if (OS_UNIX_LIKE) {

    I put the call to setAllowLinking() into a condition, because on Windows and other case-insensitive systems, calling it with true may allow a potential attacker to get the source code of JSP pages. I don’t use JSPs, but I still watch out for security risks.

Leave a Reply

Your email address will not be published. Required fields are marked *