https://issues.apache.org/bugzilla/show_bug.cgi?id=52988
Bug #: 52988 Summary: ExpandWar::deleteDir() traverses symlinked directories, deleting files outside of appBase Product: Tomcat 7 Version: 7.0.16 Platform: Other OS/Version: Linux Status: NEW Severity: normal Priority: P2 Component: Catalina AssignedTo: dev@tomcat.apache.org ReportedBy: christiw...@gmail.com CC: christiw...@gmail.com Classification: Unclassified Overview: When Tomcat fails to expand a WAR file, it attempts to clean up after itself by running deleteDir(docBase). This function contains a problematic if-condition that allows Tomcat to traverse symlinked directories and recursively delete files behind them, even if those files are outside 'docBase'. Steps to Reproduce: 1) Explode a WAR successfully into webapps/. 2) Add a symlink in that WAR's docbase to a directory outside of webapps/. As far as I can tell, it can be anywhere on the machine (ours traversed a mount, for example). 3) Redeploy a WAR, but make it fail somehow (I witnessed it while deploying a corrupted zip archive), thus activating these lines of ExpandWar.java: 158 if (!success) { 159 // If something went wrong, delete expanded dir to keep things. 160 // clean 161 deleteDir(docBase); 162 } Actual Results: deleteDir() traversed the directory symlinks in 'docBase', allowing Tomcat to incorrectly delete files outside of docBase. It appears the problem is line 374 of ExpandWar.java. Despite internet sources claiming otherwise, I was able to verify the isDirectory() method returns 'true' for symlinked directories using my version, build, and platform: 366 public static boolean deleteDir(File dir, boolean logFailure) { 367 368 String files[] = dir.list(); 369 if (files == null) { 370 files = new String[0]; 371 } 372 for (int i = 0; i < files.length; i++) { 373 File file = new File(dir, files[i]); 374 if (file.isDirectory()) { 375 deleteDir(file, logFailure); 376 } else { 377 file.delete(); 378 } Expected Results: ExpandWar.java should delete symlinks without following them. One could either check the absolute vs. canonical path, or use something like the isSymlink() method already present in Apache Commons: http://stackoverflow.com/a/813730/877115 Build Date and Platform: Sun java 1.6.0_20 running on RHEL 6.1. First discovered in 7.0.16, but I checked trunk and the troubled logic is unchanged there. Additional information: We used symlinks to link client assets inside docBase for legacy code purposes. We've refactored this code out after encountering this bug, as maintaining symlinks inside exploded WARs is difficult, a bad practice, and this bug makes them a time bomb. All the same, I can't imagine any conditions under which Tomcat's WAR logic should be able to delete files outside of 'docBase', even if the user was foolish like me. Hence this filing. -- Configure bugmail: https://issues.apache.org/bugzilla/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- You are the assignee for the bug. --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org