You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by bu...@apache.org on 2002/02/08 11:06:38 UTC

DO NOT REPLY [Bug 6324] New: - Invalid POST requests through ajp13 cause 'garbage' characters on the ServletInputStream

DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG 
RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT
<http://nagoya.apache.org/bugzilla/show_bug.cgi?id=6324>.
ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND 
INSERTED IN THE BUG DATABASE.

http://nagoya.apache.org/bugzilla/show_bug.cgi?id=6324

Invalid POST requests through ajp13 cause 'garbage' characters on the ServletInputStream

           Summary: Invalid POST requests through ajp13 cause 'garbage'
                    characters on the ServletInputStream
           Product: Tomcat 3
           Version: 3.2.3 Final
          Platform: PC
        OS/Version: Windows NT/2K
            Status: NEW
          Severity: Normal
          Priority: Other
         Component: Connectors
        AssignedTo: tomcat-dev@jakarta.apache.org
        ReportedBy: philip@rsuk.com


If a client makes a POST request through Apache mod_jk and ajp13, submits the 
headers but aborts the connection before sending the number of characters 
specified by the Content-Length header, a POST request with garbage characters 
as input will be passed to the target servlet on the input stream.  This can be 
seen by calling the getInputStream() method of HttpRequest.  The garbage 
characters appear to come from the headers of the request (see below for an 
example).

This bug affects Tomcat versions 3.2.3 and 3.2.4, running on Windows and Linux.

The bug only affects ajp13 with mod_jk.  It does not affect ajp12 or Tomcat's 
HTTP connector.  

The bug can be reproduced with the following servlet (downloadable from 
http://sonic.rsuk.com/~psr/tomcatbug/Servlet1.java):

------

package testwebapp;

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import java.util.*;

public class Servlet1 extends HttpServlet
{
    private static final String CONTENT_TYPE = "text/html";

    public void doGet(HttpServletRequest request,
    				  HttpServletResponse response)
    				  throws ServletException, IOException
    {
        response.setContentType(CONTENT_TYPE);
        PrintWriter out = response.getWriter();
        out.println("<html><body>Test</body></html>");
    }

    public void doPost(HttpServletRequest request,
    				   HttpServletResponse response)
    				   throws ServletException, IOException
    {
        System.out.println("Begin Post Request: " 
        				   + request.getRemoteAddr() 
        				   + " " 
        				   + request.getRequestURI());
        response.setContentType(CONTENT_TYPE);
        PrintWriter out = response.getWriter();

        ServletInputStream is = request.getInputStream();
        byte[] buffer = new byte[64000];
        int res;
        StringBuffer sb = new StringBuffer();

        while ((res = is.readLine(buffer, 0, buffer.length)) > 0)
        {
            String s = new String(buffer, 0, res, "ISO8859-1");
            sb.append(s);
        }

        out.print(sb.toString());
        System.out.println(sb.toString());
        System.out.println("End Post Request");
    }
}

------ 

On receiving a POST request, this servlet reads from the ServletInputStream and 
outputs the characters read to both the ServletOutputStream and System.out.

To test, Servlet1 can be deployed as part of a webapp (I deployed with the url 
pattern /servlet 1 in a webapp called testapp).  An already built webapp 
containing Servlet1 can be downloaded from 
http://sonic.rsuk.com/~psr/tomcatbug/testapp.war. 

To test, Tomcat 3.2.3 or 3.2.4 needs to be setup with the ajp13 connection 
handler and then Apache (I used version 1.3.20 on Windows and 1.3.23 on Linux) 
needs to be setup with mod_jk.  I used the version of mod_jk that came with 
Tomcat 3.2.3 and 3.2.4 for tests with the respective Tomcat versions.  I used 
the following Apache configuration:

LoadModule jk_module modules/mod_jk.dll
AddModule mod_jk.c
JkWorkersFile c:/apache/conf/workers.properties
JkLogFile  logs/jk.log
JkLogLevel error
JkMount /testapp/* ajp13

With Tomcat and Apache started, the standard UNIX telnet program can be used to 
show the error.  Telnet into the Apache web server port, and make a post 
request like the following, making sure you enter at least one carriage return 
after the last line of the post request:

POST /testapp/servlet1 HTTP/1.1
Cookie: JSESSIONID=ldh3f9z3s1
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, 
application/msword, */*
Cache-Control: no-cache
Accept-Language: en-gb
User-Agent: Test
Content-type: application/x-www-form-urlencoded
Content-length: 221
Host: localhost


The key to causing the error seems to be making the Content-length header 
larger than the actual length of posted data.

After entering the post headers and moving to the start of a new blank row, 
press Ctrl+] and type quit to close the connection.  The test servlet will 
print output like the following on standard output:

Begin Post Request: xxx.xxx.xxx.xxx /testapp/servlet1
HTTP/1.1  &#9668;/testapp/servlet1  &#9835;62.254.201.100           localhost  Q�&#9786; 
Limage/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/msword, */* &#9830; 
&#9827;en-gb cache-control no-cache  &#9829;221 � !application/x-www-form-u
End Post Request

The text printed between the begin and end post request lines is what was read 
from the ServletInputStream.

When making the request using the ajp12 connector, the request is not forwarded 
to the servlet.  When making the request through Tomcat's HTTP connector, 
Tomcat shows an IOException on the console and does not forward the request to 
the servlet.

If a non-empty, but under-length request is made, the valid part of the request 
can be read from the input stream, followed by garbage data.

The behaviour of Tomcat 3.3a is similar to 3.2.3 and 3.2.4.  Tomcat's ajp12 and 
HTTP connectors behave the same � ignoring invalid POST requests.  Tomcat 
3.3a's ajp13 connector places all input sent on the ServletInputStream.

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>