[ale] tomcat security problem
Master Wizard
mainwizard at vei.net
Wed Feb 13 14:51:19 EST 2002
As part of a security audit for an out-of-state client, I created a jsp
that can browse a server when executed. The file is attached. I have not
included the upload functionality, but it is possible.
I am making the following assumptions:
1. On *nix, the jsp runs with the permissions of the JVM, which runs
with the permissions of tomcat.
2. Any jsp container will have the same problem.
My big concern is that, in a hosting environment with the ability to run
jsp's, user a could run this kind of jsp and browse or hack into user
b's files.
Can tomcat be set up to restrict access of a jsp/servlet to certain
directories based on which directory it is in or which URL was used to
access it?
On a *nix system, damage will be limited by permissions, but on a Win*
system?
Any tips/hints/help would be appreciated.
Ed.
<%@page import="java.io.*"%>
<%@page import="java.util.*"%>
<%!
String adjustPath(String path)
{
//Required by windows as they use the escape character as the file separator
StringBuffer sb = new StringBuffer("");
StringTokenizer st = new StringTokenizer(path, "\\");
while(st.hasMoreTokens())
{
sb.append(st.nextToken() + "\\\\");
}
path = sb.toString();
if(path.endsWith("\\\\"))
{
path = path.substring(0, path.length() - 2);
}
return path;
}
%>
<%
String auditDir = "";
String thisJSP = request.getRequestURI();
//Some browsers might not be setup to recognize all file extension mime types.
//Explicitly set those here.
String[] binaryFiles = {".exe", ".com"};
String[] zipFiles = {".jar", ".zip"};
boolean contentSet = false;
auditDir = request.getParameter("DirName");
System.out.println("Audit dir = " + auditDir);
if(auditDir == null || "".equalsIgnoreCase(auditDir))
{
auditDir = application.getRealPath("/");
}
File f = null;
f= new File(auditDir);
if (f.isDirectory())
{
%>
<html>
<head><title>Security Audit</title>
<SCRIPT language='JavaScript'>
function newPage(path)
{
document.audit.DirName.value=path;
document.audit.submit.click();
}
</SCRIPT>
</head>
<body>
<FORM name="audit" action='<%=thisJSP %>' method=post>
<INPUT type=textbox size='50' name='DirName' value="<%=auditDir %>">
<INPUT type=submit name='submit' value='Open'>
</FORM>
<%
out.println("found directory " + f.toString() + "<BR>");
File[] files = f.listFiles();
for (int i=0; i < files.length; i++)
{
out.println("<br>");
if(files[i].isDirectory())
{
%>
<a onClick="newPage('<%=adjustPath(files[i].toString()) %>')" href=''>
<font color='blue'><%=files[i] %></font>
</a>
<%
}
else
{
%>
<a onClick="newPage('<%=adjustPath(files[i].toString()) %>')" href=''>
<font color='purple'><%=files[i] %></font>
</a>
<%
}
}
%>
</body>
</html>
<%
}
else
{
for(int i = 0; i < zipFiles.length; i++)
{
if(f.toString().endsWith(zipFiles[i]))
{
response.setContentType("application/x-zip-compressed");
contentSet = true;
}
}
for(int i = 0; i < binaryFiles.length; i++)
{
if(f.toString().endsWith(binaryFiles[i]))
{
response.setContentType("application/x-zip-compressed");
contentSet = true;
}
}
if(!contentSet)
{
if(getServletContext().getMimeType(f.toString()) != null)
{
response.setContentType(getServletContext().getMimeType(f.toString()));
}
else
{
response.setContentType("text/html");
}
}
FileInputStream fis = null;
ServletOutputStream sos = null;
try
{
fis = new FileInputStream(f.toString());
sos = response.getOutputStream();
byte[] buf = null;
buf = new byte[4*1024];
int bytesRead;
while((bytesRead = fis.read(buf)) != -1)
{
sos.write(buf, 0, bytesRead);
}
sos.flush();
sos.close();
}
catch(Exception e)
{
System.out.println(e.getMessage());
e.printStackTrace();
sos.flush();
sos.close();
}
finally
{
sos.close();
}
}
%>
---
This message has been sent through the ALE general discussion list.
See http://www.ale.org/mailing-lists.shtml for more info. Problems should be
sent to listmaster at ale dot org.
More information about the Ale
mailing list