I have three new web bugs to demonstrate. Each of them take advantage of how a semicolon character is interpreted by a web server or browser. Each of these bugs can be demonstrated on the latest release of Apache Tomcat 7.0.22, and the latest browsers. Exploitation of these bugs requires unique issues on a vulnerable website.
1. XSS via Request URI: Avoiding "Page Not Found" Errors With Path Parameters
Apache Tomcat is one example of a web server that supports "Path Parameters". A path parameter is extra content after a file name, separated by a semicolon. Any arbitrary content after a semicolon does not affect the landing page of a web browser. This means that http://example.com/index.jsp;derp will still return index.jsp, and not some error page. If a web application was written to reflect the "requestURI" onto a page, then an attacker can take advantage of the misstep.
http://example.com/payments.jsp;');alert(1);//
Another strange thing I found while writing this is that the path parameter can even go before the actual file:
http://example.com/;';alert(1)//payments.jsp
Mitigation:
Use getServletPath() instead of getRequestURI()
2. XSS via Logged in URL: Apache Tomcat Encoded URL's
Apache Tomcat is an implementation of the Java Servlet and JavaServer Pages technologies. By default, this technology assigns a JSESSIONID cookie to each visitor as a unique identifier. Java Servlets have a unique feature that allow the JSESSIONID to be included as part of the URL when separated by a semicolon, instead of the standard hidden HTTP Request header. Presumably this is to support browsers that can't store cookies, but I was not able to determine exactly why it supports this crazy feature. Here's an example of what an encoded URL might look like:
http://example.com/index.jsp;JSESSIONID=A2C1F690F7DA38D6742282B1FC7B9434
Unfortunately, this feature can be abused. If an attacker wanted to start a phishing campaign for a vulnerable website where he had only found XSS on an authenticated portion of the website, he could insert his own valid session identifier in the URL to initiate attacks.The attackers crafted URL could look something like this:
http://example.com/admin.jsp;JSESSIONID=A2C1F690F7DA38D6742282B1FC7B9434?s="><script>alert(1)</script>
Mitigation:
I'm not sure how to disable the use of the JSESSIONID in the URL, so if you know how please leave a note in the comments and I will update the post.
Update: Thanks John, from the comments who pointed me to a stack overflow Q&A where there is information on how to disable the use of JSESSIONID within the URL. The following can be added to the web.xml configuration file in Tomcat 7:
<session-config>
<tracking-mode>COOKIE</tracking-mode>
</session-config>
Update 2:@jonpasski informs me that the Tomcat version 6 configuration parameter disableURLRewriting = "true" will disable support for tracking Session IDs in the URL. The functionality comes as part of the Java Servlet Specification for URL Rewriting, a legacy feature to allow sessions to be tracked when clients will not accept cookies. I think it might be time for this feature to be deprecated.
3. MIME Type Detection Manipulation
This one is big. So we know that Apache Tomcat allows Path Parameters after a semicolon, and any arbitrary text can be added after a filename. Unfortunately, Internet Explorer doesn't take this into consideration and actually uses what it thinks is the file extension as one of the factors when determining file MIME type. MIME type is what tells Internet Explorer whether to open content as a webpage, or a downloadable file, or display it as an image, or run as JavaScript. An attacker can take advantage of Internet Explorer's built in MIME Type Detection, and exploit an XSS vulnerability. This is how it works:
An attacker has found what appears to be HTML code injection on a website, but the injection is wrapped in JSON punctuation, or the attacker found file upload functionality, but the extension is restricted to .doc, or .zip, etc. Either way, the web server will attempt to specify the correct content with a response header "Content-Type: application/json", which prevents most browsers from rendering any HTML or JavaScript within the response. In IE 6, 7, 8, and even 9, a file extension provided after the URL redefines the MIME type IE uses. If the attacker can trick IE into loading the file as HTML, the attacker can include malicious JavaScript to execute. The crafted url would look something like this:
http://example.com/search/derp/results.zip;.html
This trick appears to work with many file types: .doc, .flv, .jar, .pdf, .zip, .swf; basically anything except images.
The same trick apparently works on PHP sites as well, as documented on IBM's Watchfire blog. In PHP, Path Parameters are passed after a page with "/" instead of a semicolon.
This is very similar to a previous vulnerability, CVE-2009-4444: IIS 6 Filename Parsing Flaw. It's a bit old, and has been patched, but it's still an excellent flaw to test for in web applications. With the use of a semicolon, attackers can bypass file extension verification performed by applications running on Microsoft IIS. If the application only allowed users to upload files with the ".jpg" extension, an attacker could attempt to upload a file called "shell.asp;.jpg". A flaw was discovered where the web application would read the file name and see the file as a .jpg image, while the IIS server would recognize all of the text leading up the semicolon, and consider the file to be an ASP file. When accessed, the IIS server would run the malicious code inside of the file, instead of storing a benign image.
Mitigation:
Content sniffing is a longstanding behavior in Internet Explorer. To prevent exploitation of this vulnerability web application developers are encouraged to use the following headers where appropriate:
"X-Content-Type-Options: nosniff"
"X-Download-Options: noopen"
"Content-Disposition: attachment; filename=untrustedfile.html"
Try it!
I wrote a proof of concept page to demonstrate these vulnerabilities, but I will only be hosting it temporarily [noe offline]. After checking out the demo page, check out the source code:
<%@ page session="true" %>
<!DOCTYPE html>
<html>
<% response.setHeader("X-XSS-Protection","0"); %>
<head>
<title>Semicolon Jacking</title>
</head>
<body>
<%
if ( session.getLastAccessedTime() <= session.getCreationTime() ) {
out.println("You are not logged in!<br/><br/>");
}
else if ( session.getLastAccessedTime() > session.getCreationTime() ) {
out.println("You are logged in!<br/>");
out.println("Reflected Paramter: "+request.getParameter("xss")+"<br/><br/>");
}
%>
<script>var pageUri = '${pageContext.request.requestURI}';</script>
<br/>1. XSS via Request URI (Webkit/IE/Opera):<br/> <a href="/semicolon.jsp;';alert('xss1')-'">/semicolon.jsp;';alert('xss1')-'</a>
<br/>
<%
String originalURL = "/semicolon.jsp?xss=%3cimg%20src%3dx%20onerror%3dalert(/xss2/)%3e";
String encodedURL = response.encodeURL(originalURL);
out.println("<br/>2. XSS via Logged in URL:<br/> <a href=\""+encodedURL+"\">"+encodedURL+"</a>");
%>
<br/><br/>3. MIME Type Detection Manipulation (IE Only):<br/> <a href="/xss.zip;.html">/xss.zip;.html</a>
</br/> <a href="/xss.jar;.html">/xss.jar;.html</a>
<br/> <a href="/xss.doc;.html">/xss.doc;.html</a>
<br/> <a href="/xss.exe;.html">/xss.exe;.html</a>
<br/>
<br/>
<br/><br/><br/>DEBUG:
<br/>X-XSS-Protection: 0
<br/>session.id: ${pageContext.session.id}
<br/>session.lastAccessedTime: ${pageContext.session.lastAccessedTime}
<br/>session.reationTime: ${pageContext.session.creationTime}
<br/>requestURI: ${pageContext.request.requestURI}
<br/>queryString: ${pageContext.request.queryString}
<br/>PathTranslated: ${pageContext.request.pathTranslated}
<br/>PathInfo: ${pageContext.request.pathInfo}
<br/>ServletPath: ${pageContext.request.servletPath}
</body>
</html>
Each of the sample files for Vulnerability #3 contain only one line of text:
<html><script>alert('XSS')</script></html>
References:
RFC3986: Uniform Resource Identifier (URI): Generic Syntax http://tools.ietf.org/html/rfc3986#section-3.3
Microsoft IIS 0Day Vulnerability in Parsing Files (semi-colon bug) http://soroush.secproject.com/downloadable/iis-semicolon-report.pdf
Ignoring Content-Type of IE http://utf-8.jp/public/20110723/hitcon-hasegawa.pptx
IE8 Security: Comprehensive Protection http://blogs.msdn.com/b/ie/archive/2008/07/02/ie8-security-part-v-comprehensive-protection.aspx