tomcat-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Michael Osipov <micha...@apache.org>
Subject Possible bug in HttpServletRequest#getRequestDispatcher()
Date Wed, 25 Jul 2018 20:13:14 GMT
Hi folks,

I might have found a bug and looking for someone to confirm. (Tested in 
Tomcat 8.5.32).

Consider the following servlet:
> @WebServlet("/request-dispatcher")
> public class TestServlet extends HttpServlet {
> 	private static final long serialVersionUID = 1L;
> 
> 	protected void doGet(HttpServletRequest request, HttpServletResponse response)
> 			throws ServletException, IOException {
> 		String jsp = request.getParameter("jsp");
> 		if (jsp == null || jsp.isEmpty())
> 			response.sendError(HttpServletResponse.SC_BAD_REQUEST);
> 		else {
> 			System.out.println("Requested JSP: " + jsp);
> 			RequestDispatcher dispatcher = request.getRequestDispatcher("/" + jsp);
> 			dispatcher.forward(request, response);
> 		}
> 	}
> }

Now this call:
> $ curl --verbose http://localhost:8080/test/request-dispatcher?jsp=1380%2B0.jsp
> * STATE: INIT => CONNECT handle 0x25de150; line 1392 (connection #-5000)
> * Added connection 0. The cache now contains 1 members
> * STATE: CONNECT => WAITRESOLVE handle 0x25de150; line 1428 (connection #0)
>   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
>                                  Dload  Upload   Total   Spent    Left  Speed
>   0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0*   Trying
::1...
> * TCP_NODELAY set
> * STATE: WAITRESOLVE => WAITCONNECT handle 0x25de150; line 1509 (connection #0)
> * Connected to localhost (::1) port 8080 (#0)
> * STATE: WAITCONNECT => SENDPROTOCONNECT handle 0x25de150; line 1561 (connection #0)
> * Marked for [keep alive]: HTTP default
> * STATE: SENDPROTOCONNECT => DO handle 0x25de150; line 1579 (connection #0)
>> GET /test/request-dispatcher?jsp=1380%2B0.jsp HTTP/1.1
>> Host: localhost:8080
>> User-Agent: curl/7.58.0
>> Accept: */*
>>
> * STATE: DO => DO_DONE handle 0x25de150; line 1658 (connection #0)
> * STATE: DO_DONE => WAITPERFORM handle 0x25de150; line 1783 (connection #0)
> * STATE: WAITPERFORM => PERFORM handle 0x25de150; line 1799 (connection #0)
> * HTTP 1.1 or later with persistent connection, pipelining supported
> < HTTP/1.1 404
> < Content-Type: text/html;charset=utf-8
> < Content-Language: en
> < Content-Length: 1093
> < Date: Wed, 25 Jul 2018 19:44:30 GMT

Now this one:
> $ curl -I http://localhost:8080/test/1380+0.jsp --verbose                       * STATE:
INIT => CONNECT handle 0x66e150; line 1392 (connection #-5000)
> * Added connection 0. The cache now contains 1 members
> * STATE: CONNECT => WAITRESOLVE handle 0x66e150; line 1428 (connection #0)
>   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
>                                  Dload  Upload   Total   Spent    Left  Speed
>   0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0*   Trying
::1...
> * TCP_NODELAY set
> * STATE: WAITRESOLVE => WAITCONNECT handle 0x66e150; line 1509 (connection #0)
> * Connected to localhost (::1) port 8080 (#0)
> * STATE: WAITCONNECT => SENDPROTOCONNECT handle 0x66e150; line 1561 (connection #0)
> * Marked for [keep alive]: HTTP default
> * STATE: SENDPROTOCONNECT => DO handle 0x66e150; line 1579 (connection #0)
>> HEAD /test/1380+0.jsp HTTP/1.1
>> Host: localhost:8080
>> User-Agent: curl/7.58.0
>> Accept: */*
>>
> * STATE: DO => DO_DONE handle 0x66e150; line 1658 (connection #0)
> * STATE: DO_DONE => WAITPERFORM handle 0x66e150; line 1783 (connection #0)
> * STATE: WAITPERFORM => PERFORM handle 0x66e150; line 1799 (connection #0)
> * HTTP 1.1 or later with persistent connection, pipelining supported
> < HTTP/1.1 200
> < Set-Cookie: JSESSIONID=FC911829DB08950A03808483C61DFBDF; Path=/test; HttpOnly
> < Content-Type: text/html;charset=UTF-8
> < Transfer-Encoding: chunked
> < Date: Wed, 25 Jul 2018 19:45:12 GMT

I know that #getRequestDispatcher() requires a RFC 3986 compliant URI 
which this one is according to JS' encodeURI().

The root cause, imho, is ApplicationContext.java:432:
> decodedPath = URLDecoder.decode(normalizedPath, "UTF-8");

This is deemed to fail because URLDecoder has not been designed for 
URIs, but for "This class contains static methods for decoding a String 
from the application/x-www-form-urlencoded MIME format."

It is used in
> ApplicationContext.java
> WebappLoader.java
> CGIServlet.java
> JspRuntimeContext.java

I consider this to be a bug, I know that Tomcat has its own URLEncoder, 
but it seems that we need a compliant URLDecoder or use UDecoder?.

Can someone confirm?

Michael

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Mime
View raw message